Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
0.00% covered (danger)
0.00%
0 / 3013
0.00% covered (danger)
0.00%
0 / 164
CRAP
0.00% covered (danger)
0.00%
0 / 1
iacase
0.00% covered (danger)
0.00%
0 / 3013
0.00% covered (danger)
0.00%
0 / 164
3525006
0.00% covered (danger)
0.00%
0 / 1
 __construct
0.00% covered (danger)
0.00%
0 / 22
0.00% covered (danger)
0.00%
0 / 1
90
 process_action
0.00% covered (danger)
0.00%
0 / 76
0.00% covered (danger)
0.00%
0 / 1
930
 process
0.00% covered (danger)
0.00%
0 / 38
0.00% covered (danger)
0.00%
0 / 1
1190
 iaHeader_need_listme
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 iaHeader_need_form
0.00% covered (danger)
0.00%
0 / 16
0.00% covered (danger)
0.00%
0 / 1
30
 iaHeader_need_has
0.00% covered (danger)
0.00%
0 / 21
0.00% covered (danger)
0.00%
0 / 1
306
 add_default_values
0.00% covered (danger)
0.00%
0 / 8
0.00% covered (danger)
0.00%
0 / 1
12
 add_adhoc_params
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 params_to_value
0.00% covered (danger)
0.00%
0 / 20
0.00% covered (danger)
0.00%
0 / 1
272
 validate_delete
0.00% covered (danger)
0.00%
0 / 21
0.00% covered (danger)
0.00%
0 / 1
462
 validate
0.00% covered (danger)
0.00%
0 / 95
0.00% covered (danger)
0.00%
0 / 1
2652
 insert_do
0.00% covered (danger)
0.00%
0 / 21
0.00% covered (danger)
0.00%
0 / 1
30
 insert
0.00% covered (danger)
0.00%
0 / 12
0.00% covered (danger)
0.00%
0 / 1
30
 insert_pre_validate
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 insert_validate
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 insert_pre_save
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 insert_extra_values
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 insert_extra_sql
n/a
0 / 0
n/a
0 / 0
1
 insert_add_sql_queries
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 insert_save
0.00% covered (danger)
0.00%
0 / 67
0.00% covered (danger)
0.00%
0 / 1
930
 insert_post_save
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 update_do
0.00% covered (danger)
0.00%
0 / 26
0.00% covered (danger)
0.00%
0 / 1
42
 update
0.00% covered (danger)
0.00%
0 / 12
0.00% covered (danger)
0.00%
0 / 1
56
 update_pre_validate
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 update_validate
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 update_pre_save
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 update_add_sql_queries
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 update_extra_sql
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 update_save
0.00% covered (danger)
0.00%
0 / 23
0.00% covered (danger)
0.00%
0 / 1
72
 update_post_save
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 delete_do
0.00% covered (danger)
0.00%
0 / 41
0.00% covered (danger)
0.00%
0 / 1
240
 delete_pre_validate
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 delete_post_validate
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 delete_pre_confirm_delete
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 delete_pre_delete
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 delete_post_delete
n/a
0 / 0
n/a
0 / 0
1
 delete_sql
0.00% covered (danger)
0.00%
0 / 10
0.00% covered (danger)
0.00%
0 / 1
240
 delete_sql_extra
n/a
0 / 0
n/a
0 / 0
1
 export_record
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 log_field
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 log
0.00% covered (danger)
0.00%
0 / 19
0.00% covered (danger)
0.00%
0 / 1
132
 msg_show
0.00% covered (danger)
0.00%
0 / 2
0.00% covered (danger)
0.00%
0 / 1
6
 form_edit_view_delete_prepare
0.00% covered (danger)
0.00%
0 / 30
0.00% covered (danger)
0.00%
0 / 1
210
 form_alta_prepare
0.00% covered (danger)
0.00%
0 / 18
0.00% covered (danger)
0.00%
0 / 1
42
 form_tag
0.00% covered (danger)
0.00%
0 / 27
0.00% covered (danger)
0.00%
0 / 1
1056
 forma_insert
0.00% covered (danger)
0.00%
0 / 2
0.00% covered (danger)
0.00%
0 / 1
2
 forma_update
0.00% covered (danger)
0.00%
0 / 2
0.00% covered (danger)
0.00%
0 / 1
2
 forma_read
0.00% covered (danger)
0.00%
0 / 2
0.00% covered (danger)
0.00%
0 / 1
2
 forma_delete_confirm
0.00% covered (danger)
0.00%
0 / 2
0.00% covered (danger)
0.00%
0 / 1
2
 forma_deleted_feedback
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 forma
0.00% covered (danger)
0.00%
0 / 7
0.00% covered (danger)
0.00%
0 / 1
20
 forma_pre
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 forma_post
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 forma_preFields
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 forma_postFields
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 forma_doChilds
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 forma_postDiv
0.00% covered (danger)
0.00%
0 / 3
0.00% covered (danger)
0.00%
0 / 1
30
 forma_miniLog
0.00% covered (danger)
0.00%
0 / 10
0.00% covered (danger)
0.00%
0 / 1
110
 forma_sequencial
0.00% covered (danger)
0.00%
0 / 41
0.00% covered (danger)
0.00%
0 / 1
1640
 divDataTableStyle
0.00% covered (danger)
0.00%
0 / 5
0.00% covered (danger)
0.00%
0 / 1
42
 forma_deduce
0.00% covered (danger)
0.00%
0 / 81
0.00% covered (danger)
0.00%
0 / 1
4830
 forma_deduce4PDF
0.00% covered (danger)
0.00%
0 / 58
0.00% covered (danger)
0.00%
0 / 1
1640
 child_tables_show_all
0.00% covered (danger)
0.00%
0 / 20
0.00% covered (danger)
0.00%
0 / 1
90
 qbe_forma
0.00% covered (danger)
0.00%
0 / 39
0.00% covered (danger)
0.00%
0 / 1
600
 miniLogField
0.00% covered (danger)
0.00%
0 / 9
0.00% covered (danger)
0.00%
0 / 1
240
 miniLog
0.00% covered (danger)
0.00%
0 / 23
0.00% covered (danger)
0.00%
0 / 1
182
 miniStats
0.00% covered (danger)
0.00%
0 / 10
0.00% covered (danger)
0.00%
0 / 1
42
 miniLoginLog
0.00% covered (danger)
0.00%
0 / 12
0.00% covered (danger)
0.00%
0 / 1
42
 qbe_where
0.00% covered (danger)
0.00%
0 / 49
0.00% covered (danger)
0.00%
0 / 1
506
 qbe_resultados
0.00% covered (danger)
0.00%
0 / 4
0.00% covered (danger)
0.00%
0 / 1
2
 listme_pre
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 listme_preRender
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 listme_postRender
n/a
0 / 0
n/a
0 / 0
1
 listme
0.00% covered (danger)
0.00%
0 / 64
0.00% covered (danger)
0.00%
0 / 1
1056
 iajqgrid_actions
0.00% covered (danger)
0.00%
0 / 28
0.00% covered (danger)
0.00%
0 / 1
600
 child_jqgrid_actions
0.00% covered (danger)
0.00%
0 / 22
0.00% covered (danger)
0.00%
0 / 1
420
 toolbar_set
0.00% covered (danger)
0.00%
0 / 136
0.00% covered (danger)
0.00%
0 / 1
812
 display_toolbar
0.00% covered (danger)
0.00%
0 / 94
0.00% covered (danger)
0.00%
0 / 1
4422
 sin_permiso
0.00% covered (danger)
0.00%
0 / 5
0.00% covered (danger)
0.00%
0 / 1
2
 h_a_permiso
0.00% covered (danger)
0.00%
0 / 8
0.00% covered (danger)
0.00%
0 / 1
72
 may_add
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 may_insert
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 may_edit
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 may_update
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
12
 may_delete
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
12
 may_read
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 may_list
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 may_export
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 may_print
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 may_viewLog
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 permiso_por_record
n/a
0 / 0
n/a
0 / 0
1
 permiso_por_tabla
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 permiso_por_campo
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 puedo_base
0.00% covered (danger)
0.00%
0 / 12
0.00% covered (danger)
0.00%
0 / 1
90
 puedo_campo
0.00% covered (danger)
0.00%
0 / 4
0.00% covered (danger)
0.00%
0 / 1
6
 title_tag
0.00% covered (danger)
0.00%
0 / 5
0.00% covered (danger)
0.00%
0 / 1
30
 label_tag
0.00% covered (danger)
0.00%
0 / 30
0.00% covered (danger)
0.00%
0 / 1
756
 label_field
0.00% covered (danger)
0.00%
0 / 7
0.00% covered (danger)
0.00%
0 / 1
42
 label_record
0.00% covered (danger)
0.00%
0 / 7
0.00% covered (danger)
0.00%
0 / 1
20
 label_record_summary
0.00% covered (danger)
0.00%
0 / 2
0.00% covered (danger)
0.00%
0 / 1
2
 label_add
0.00% covered (danger)
0.00%
0 / 6
0.00% covered (danger)
0.00%
0 / 1
12
 label_list
0.00% covered (danger)
0.00%
0 / 3
0.00% covered (danger)
0.00%
0 / 1
6
 label_table_singular
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 label_table_plural
0.00% covered (danger)
0.00%
0 / 3
0.00% covered (danger)
0.00%
0 / 1
6
 show
0.00% covered (danger)
0.00%
0 / 13
0.00% covered (danger)
0.00%
0 / 1
90
 display
0.00% covered (danger)
0.00%
0 / 94
0.00% covered (danger)
0.00%
0 / 1
4422
 display_link
0.00% covered (danger)
0.00%
0 / 14
0.00% covered (danger)
0.00%
0 / 1
72
 display_set
0.00% covered (danger)
0.00%
0 / 12
0.00% covered (danger)
0.00%
0 / 1
56
 display_file_list
0.00% covered (danger)
0.00%
0 / 41
0.00% covered (danger)
0.00%
0 / 1
552
 display_json_file_list
0.00% covered (danger)
0.00%
0 / 11
0.00% covered (danger)
0.00%
0 / 1
110
 input_auto
0.00% covered (danger)
0.00%
0 / 119
0.00% covered (danger)
0.00%
0 / 1
2970
 input_link_sql
0.00% covered (danger)
0.00%
0 / 16
0.00% covered (danger)
0.00%
0 / 1
110
 input_link_array
0.00% covered (danger)
0.00%
0 / 67
0.00% covered (danger)
0.00%
0 / 1
992
 radio_checkbox
0.00% covered (danger)
0.00%
0 / 14
0.00% covered (danger)
0.00%
0 / 1
56
 input_date
0.00% covered (danger)
0.00%
0 / 5
0.00% covered (danger)
0.00%
0 / 1
12
 input_date_combos
0.00% covered (danger)
0.00%
0 / 45
0.00% covered (danger)
0.00%
0 / 1
182
 input_date_mobiscroll
0.00% covered (danger)
0.00%
0 / 19
0.00% covered (danger)
0.00%
0 / 1
30
 input_date_datepicker
0.00% covered (danger)
0.00%
0 / 23
0.00% covered (danger)
0.00%
0 / 1
56
 input_datetime
0.00% covered (danger)
0.00%
0 / 23
0.00% covered (danger)
0.00%
0 / 1
56
 input_date_alt
0.00% covered (danger)
0.00%
0 / 3
0.00% covered (danger)
0.00%
0 / 1
6
 date_max_min
0.00% covered (danger)
0.00%
0 / 8
0.00% covered (danger)
0.00%
0 / 1
72
 input_anoMes
0.00% covered (danger)
0.00%
0 / 52
0.00% covered (danger)
0.00%
0 / 1
380
 input_file
0.00% covered (danger)
0.00%
0 / 18
0.00% covered (danger)
0.00%
0 / 1
42
 input_number
0.00% covered (danger)
0.00%
0 / 15
0.00% covered (danger)
0.00%
0 / 1
72
 autonumeric_attribute
0.00% covered (danger)
0.00%
0 / 31
0.00% covered (danger)
0.00%
0 / 1
702
 ori_field
0.00% covered (danger)
0.00%
0 / 13
0.00% covered (danger)
0.00%
0 / 1
72
 set_name_id_and_value
0.00% covered (danger)
0.00%
0 / 30
0.00% covered (danger)
0.00%
0 / 1
506
 atribute_set
0.00% covered (danger)
0.00%
0 / 4
0.00% covered (danger)
0.00%
0 / 1
20
 atribute_setIfNotExists
0.00% covered (danger)
0.00%
0 / 2
0.00% covered (danger)
0.00%
0 / 1
6
 atribute_remove
0.00% covered (danger)
0.00%
0 / 2
0.00% covered (danger)
0.00%
0 / 1
6
 atribute_toString
0.00% covered (danger)
0.00%
0 / 5
0.00% covered (danger)
0.00%
0 / 1
30
 campos_set_required
0.00% covered (danger)
0.00%
0 / 4
0.00% covered (danger)
0.00%
0 / 1
42
 campos_set_attribute
0.00% covered (danger)
0.00%
0 / 6
0.00% covered (danger)
0.00%
0 / 1
30
 campos_push_attribute
0.00% covered (danger)
0.00%
0 / 8
0.00% covered (danger)
0.00%
0 / 1
30
 campos_append_attribute
0.00% covered (danger)
0.00%
0 / 8
0.00% covered (danger)
0.00%
0 / 1
30
 colmodel_set_attribute
0.00% covered (danger)
0.00%
0 / 24
0.00% covered (danger)
0.00%
0 / 1
342
 defaults_set
0.00% covered (danger)
0.00%
0 / 6
0.00% covered (danger)
0.00%
0 / 1
20
 read_sql
0.00% covered (danger)
0.00%
0 / 22
0.00% covered (danger)
0.00%
0 / 1
306
 list_sql
n/a
0 / 0
n/a
0 / 0
1
 insert_sql
0.00% covered (danger)
0.00%
0 / 50
0.00% covered (danger)
0.00%
0 / 1
1260
 update_sql
0.00% covered (danger)
0.00%
0 / 62
0.00% covered (danger)
0.00%
0 / 1
1892
 strim
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 nl2br
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 br2nl
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 files_upload
0.00% covered (danger)
0.00%
0 / 73
0.00% covered (danger)
0.00%
0 / 1
2070
 file_extension_valid
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 files_valid
0.00% covered (danger)
0.00%
0 / 19
0.00% covered (danger)
0.00%
0 / 1
1056
 files_deduce_dir
0.00% covered (danger)
0.00%
0 / 14
0.00% covered (danger)
0.00%
0 / 1
30
 files_ensurePath
0.00% covered (danger)
0.00%
0 / 13
0.00% covered (danger)
0.00%
0 / 1
42
 files_ensuereDir
0.00% covered (danger)
0.00%
0 / 6
0.00% covered (danger)
0.00%
0 / 1
12
 campo_key
0.00% covered (danger)
0.00%
0 / 2
0.00% covered (danger)
0.00%
0 / 1
12
 campo_atribute_val
0.00% covered (danger)
0.00%
0 / 16
0.00% covered (danger)
0.00%
0 / 1
42
 atribute_set_from_campo
0.00% covered (danger)
0.00%
0 / 5
0.00% covered (danger)
0.00%
0 / 1
12
 child_tables_default
0.00% covered (danger)
0.00%
0 / 10
0.00% covered (danger)
0.00%
0 / 1
240
 child_table_get
0.00% covered (danger)
0.00%
0 / 36
0.00% covered (danger)
0.00%
0 / 1
650
 child_table_save_all
0.00% covered (danger)
0.00%
0 / 6
0.00% covered (danger)
0.00%
0 / 1
42
 child_table_save
0.00% covered (danger)
0.00%
0 / 76
0.00% covered (danger)
0.00%
0 / 1
4160
 array_val
0.00% covered (danger)
0.00%
0 / 2
0.00% covered (danger)
0.00%
0 / 1
6
 to_label
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
6
 child_table_key_value_select
0.00% covered (danger)
0.00%
0 / 39
0.00% covered (danger)
0.00%
0 / 1
210
 child_table_multiselect
0.00% covered (danger)
0.00%
0 / 21
0.00% covered (danger)
0.00%
0 / 1
182
 child_table_jqgrid
0.00% covered (danger)
0.00%
0 / 121
0.00% covered (danger)
0.00%
0 / 1
4032
 child_listme_preRender
n/a
0 / 0
n/a
0 / 0
1
 child_listme_postRender
n/a
0 / 0
n/a
0 / 0
1
 child_table_addonly
0.00% covered (danger)
0.00%
0 / 12
0.00% covered (danger)
0.00%
0 / 1
30
 child_table_edit
0.00% covered (danger)
0.00%
0 / 62
0.00% covered (danger)
0.00%
0 / 1
2970
 child_table_list
0.00% covered (danger)
0.00%
0 / 47
0.00% covered (danger)
0.00%
0 / 1
3080
 exporta_listado_csv
0.00% covered (danger)
0.00%
0 / 30
0.00% covered (danger)
0.00%
0 / 1
380
 campos_reorder
0.00% covered (danger)
0.00%
0 / 8
0.00% covered (danger)
0.00%
0 / 1
30
 simulated_fields
0.00% covered (danger)
0.00%
0 / 3
0.00% covered (danger)
0.00%
0 / 1
6
 simulated_fields_mysqli
0.00% covered (danger)
0.00%
0 / 16
0.00% covered (danger)
0.00%
0 / 1
42
 simulated_fields_mysql
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
1<?php
2/** @noinspection PhpMissingFieldTypeInspection */
3/** @noinspection PhpMissingReturnTypeInspection */
4/** @noinspection PhpMissingParamTypeInspection */
5/** @noinspection RegExpRedundantEscape */
6/** @noinspection PhpRedundantOptionalArgumentInspection */
7/** @noinspection PhpDefineCanBeReplacedWithConstInspection */
8/** @noinspection SqlNoDataSourceInspection */
9/** @noinspection SqlResolve */
10/** @noinspection SqlSignature */
11
12/**
13 * iacase
14 * 
15 * @package iacase
16 * @author raul j.
17 * @copyright 2012
18 * @version $Id$ 1.3 2013-12-19
19 * @access public
20 */
21class iacase {
22public $debug=false;
23    public $modo='cardex';      // cardex misma ventana, cardex_window cardex in new window, jqgrid_iacform forma de iacase, jqgrid_form forma de jqgrid, jqgrid_inline (inline falta; feedback save y delete params/feedback)
24    public $child_modo='cardex_window';
25
26    public $paramsAmp = '';
27
28    // por ahora despues de cambiar modo llamar iajqgrid_actions
29    public $dialog_soy=false; // se pone solito en true en modo=cardex_window
30    public $log_cardex_view=false; // true log each iah=r pageview
31    public $count_backoffice_view=true;
32    public $cols_read='*';      // columnas a leer
33    public $cols_update='*';
34    public $cols_insert='*';
35
36    public $list_where='';      // filtro para el list iacwhere de jqgrid
37    public $cols_export='*';
38    public $cols_search='*';
39
40    public $asChild=false;      // en true esta instancia es child table
41    public $childTables=array();  // childTables storage
42    public $childTablesUse=array(); // solo considera estos child tables
43    public $saveChilds=true;    // en false no hace child tables en el save
44    public $editChilds=true;    // en false no saca tablita add another editar childs
45    public $deleteChilds=false;    // en true, permite sacar el botón de borrar
46    public $editChildsSetRO=false; // forza a todos los childs a ser R/O!
47    public $viewChilds=true;    // en false no muestra childs
48    public $childHide=array(); // array('childTableToHide');
49    public $child_jqGrid_height=300;
50    public $child_jqGrid_width="'50%'";
51    public $child_jqGrid_option=array(); // options a poner en el jqgrid array('autowidth'=>true,...)
52    public $child_jqGrid_cols=array();
53    public $child_jqGrid_hiddenCols=array();
54    public $child_jqgrid_colModelOverride=array(); // array( 'colname'=>array('colModelOption'=>'',...),... )
55    public $child_jqGridSaveState=true; // guarda grid state
56    public $jqChildGridActions=array(); //actions cuando es child
57    public $formTypeChildsPerRow=2;
58    public $asChild_update=true; // usandose como child es and permsio_update
59    public $asChild_delete=true; // usandose como child es and permsio_update
60
61    public $cols_list='*';
62    public $list_sortname_dflt='';
63    public $list_sortorder_dflt='';
64    public $col_list_noShow=array();    // estas ni llegan al jqgrid
65
66    public $jqGridEditable=true;
67    public $jqGridHiddenCols=array(); // estas llegan al grid pero quedan hidden
68    public $jqGridId_Prefix='iajqgrid'; // para cambiar en iacase_base el nombre de todos los grids
69    public $jqGridId=null; // por default $this->jqGridId =$this->jqGridId_Prefix.$this->table; //Solo cambiar en constructor de app_
70    public $jqGridSaveState=true; // guarda grid state
71    public $jqGridFilters=true; // pone o quita filters de jqgrid
72    public $jqGridFiltersVisible=false; // filters visibles inicialmente
73    public $jqGridSearch=true; // pone o quita search de jqgrid
74    public $jqGridSendOnly=array(); // mandar unicamente estas columnas
75    public $colModel_overRide=array(); // override generated colModel
76    public $jqGridSelect=''; // select  a usar en vez del default para el jqgrid
77    public $jqGridExtraWhere=''; // where a agregar
78    public $useJqueryValidate=false;
79    public $jqGridActions=array(); //la llena en automnatico $this->iajqgrid_actions(), aqui van las finales llena los defaults segun $modo
80    public $iajqgrid_actions_extra=array(); // llenar con las extra
81    public $jqGrid_options=array(); // options a poner en el jqgrid array('autowidth'=>true,...)
82
83    public $useFormChanged=true;
84    public $useBlockUI=true;
85    // falta classes?: table container, row, cell, cell title, div-label
86    public $data_div_edit='dved';               // css class div for label-field edit/add
87    public $data_div_read='dvrd';               // css class div for label-field view/read
88    public $label_class='bold lbl';              // css class field <label>
89    public $label_error_class='lbler';      // css class field error <label>
90    public $label_required_class='lblrq';   // css class field required no error <label>
91    public $label_required_mark='* ';
92    public $label_optional_mark='&nbsp;';
93    public $label_group='lblgrp';           // css class grupos de campos
94
95    public $primary_key_show=false; // mostrar el primary key en las formas o no
96
97    public $bit_field_display=array( 'true'=>'X','false'=>'&nbsp;');  // en bit field true mostrar
98
99    public $dialog_input_max_size=20;
100    public $input_max_size=40;          // en cardex
101    public $input_max_size_child=30;    // en child
102
103    public $seleccione='Seleccione'; // combos con null
104    public $input_date_widget='datepicker'; // (mobiscroll, datepicker, combos) default datepicker falta
105    public $input_datetime_widget='datepicker'; // (mobiscroll, datepicker) default datepicker falta
106    public $input_time_widget='datepicker'; // (mobiscroll, datepicker) default datepicker falta
107    public $input_anomes_widget='combos'; // (mobiscroll, combos) default combos falta
108    public $select_multiple_size=8;
109    public $attachments_private=false;
110    public $textarea_style='';
111    public $textarea_rows=10;
112    public $textarea_cols=80;
113    public $medium_textarea_rows=5;
114    public $medium_textarea_cols=40;
115    public $text_textarea_rows=3;
116    public $text_textarea_cols=20;
117    public $display_element=''; // div, span, ...
118    public $display_email_link=true;
119    public $display_url_link=true;
120    public $formType='deduce'; // deduce, secuencial, db
121    public $formTypeSecuencialCols=4;
122
123
124    // permisos base ver may_xxx para permiso final
125
126    public $permiso_app=null; // override con const PERMISO_POR_* en appRelateBase.php
127    public $permiso_list=true;
128    public $permiso_read=true;
129    public $permiso_export=true;
130    public $permiso_insert=true;
131    public $permiso_update=true;
132    public $permiso_delete=true;
133    public $min_delete_id=0; // no vale delete id menor a esto null no aplica
134
135
136    public $esRetry=false;      // interna para ver si marcar errores label en rojo
137    public $table='';          // table name
138
139
140    public $pk_field='';        // single primary key field name
141    public $table_info=array(); // alias de appRelate->tables[$this->table]
142    public $campos=array();     // info de los campos
143    public $label='';           // titulo de la tabla
144
145
146    public $h='';               // iah actual
147    public $h_next='';          // sigueinte h en la forma
148    public $id=null;            // id (primary key del current record)
149
150
151    public $usuario_id=0;
152    public $usuario='';         // nick del usuario
153
154    public $enDB=array();       // valores en db
155    public $values=array();     // values del registro
156    public $ori=array();        // datos originales
157    public $conOri=true;        // ori check for update / log
158
159    public $formId='frm';           // id del tag form
160    public $extraParams=array();    // parametros extra en links
161
162    public $msg_err='';
163    public $msg_aviso='';
164
165    const ADD_NO_PARAMS=0;
166    const ADD_ALL_PARAMS=1;
167    const ADD_ADHOC_PARAMS=2;
168
169    public $toolbar;
170    public $jsvars;
171
172    public $changedMainTable=array(); // en update esto es que cambio
173
174    public $jsscripts=''; // jsscript despues de jsvars
175    public $busqueda_rapida_automatica=false; // activa la busqueda rápida
176    public $_app_name=''; // Test
177    public $_app_prefix=''; // Test
178    public $_cat_prefix=''; // Test
179    public $_grid_ondblClickRow=true; // $_grid_ondblClickRow
180    public $_grid_onClickRow=true; // $_grid_onClickRow
181    public $child_jqGrid_extrawhere="";
182    public $view_in_actions = false;
183    public $jgGridVar = true;
184    public bool $tbhtml = false;
185    public $jqgCat  = "";
186    public $catDoc  = "";
187    public $catAll = "";
188    public $catDef  = "";
189    public $doChilds  = true;
190    public $ignoreShowOverride  = false;
191    public $jqGridSumCols;
192    public $toolbarTitle ;
193    public $actions_width ;
194    public $exportarPDF ;
195    public $activeBA;
196    public $child_label_prefixme;
197    public $gridId;
198    public $plural ;
199    public $labels ;
200    public $label_plural ;
201    public $numerodeACuentas  ;
202    public $modoShow='html';
203////////////////////////////////////////////////////
204//  constructor
205////////////////////////////////////////////////////
206    /**
207     * iacase::__construct()
208     *
209     * @param string $h
210     * @param mixed $table
211     * @param mixed $seccion
212     * @param mixed $usuario_id
213     * @param mixed $usuario
214     * @return
215     */
216    function __construct($h='r',$table='',$seccion='',$usuario_id=null,$usuario=null) {
217    global $gAppRelate;
218        if(!isset($gAppRelate) || empty($gAppRelate) )
219            $gAppRelate = new appRelate();
220        $this->_app_name=$this->table=$table;
221        $this->jqGridId=$this->jqGridId_Prefix.$this->table;
222        $this->formId="iafrm_$this->table";
223        $gAppRelate->tables[$this->table]['has_datetime']=true;
224        $this->table_info=$gAppRelate->tables[$this->table];
225
226        if( array_key_exists('pk_single_field',$this->table_info) ) {
227            $this->pk_field=$this->table_info['pk_single_field'];
228        } else {
229            $this->pk_field='';
230            $this->table_info['pk_single_field'] = '';
231        }
232        if( array_key_exists('label',$this->table_info))
233            $this->label=$this->table['label'];
234        else
235            $this->label=to_label($table);
236
237        $this->h=param('iah',$h);
238        $this->id=param('iaid', param('id', param($this->pk_field) ));
239
240        if($usuario_id==null)
241            $this->usuario_id=isset($_SESSION['uid']) ? $_SESSION['uid'] : '0';
242        else
243            $this->usuario_id=$usuario_id;
244        if($usuario==null)
245            $this->usuario= isset($_SESSION['usuario']) ? $_SESSION['usuario'] : '?';
246        else
247            $this->usuario=$usuario;
248        //falta checar seguridad
249        //$this->permiso_por_tabla($h,$seccion);
250
251
252    }
253
254////////////////////////////////////////////////////
255// Procesar va asi: process_action head body header process footer
256////////////////////////////////////////////////////
257
258    /**
259     * iacase::process_action()
260     *
261     * @param string $h
262     * @param string $id
263     * @return
264     */
265    function process_action(&$h=null,&$id=null) {
266    global $gIaHeader;
267        if(!isset($gIaHeader) || empty($gIaHeader) )
268            $gIaHeader = new iaHeader();
269        if( array_key_exists('has_fckeditor',$this->table_info) &&  $this->table_info['has_fckeditor'] )
270            $gIaHeader->html_head_add( 'fckeditor');
271        $gIaHeader->html_head_add( 'datetimepicker');
272        $this->esRetry=false;
273        if($h==null)
274            $h=param('iah');
275        $this->h=$h;
276        if($h=='export') {
277            if($this->may_export()) {
278                $this->export_record();
279                die();
280            } else {
281                $this->h=$h='sinpermiso';
282                die("SIN PERMISO");
283            }
284        }
285
286        if($this->modo=='jqgrid_iacform')
287            $this->iaHeader_need_form();
288        if(param('iacexp')!='') {
289            if($this->may_export()) {
290                if(param('iacexp')=='csv')
291                    $this->exporta_listado_csv();
292            } else {
293                $h=$this->h='sinpermiso';
294                $this->msg_err.="<li>No tiene permiso de exportar.";
295            }
296        }
297        if($h=='qbe') {
298            $this->iaHeader_need_form();
299            $this->h_next='qbr';
300            return true;
301        }
302        if($h=='qbr') {
303            $this->iaHeader_need_listme();
304            return true;
305        }
306
307        if($h=='' || $this->modo=='jqgrid_form'  || $this->modo=='jqgrid_inline' ) {
308            $this->iaHeader_need_listme();
309            return true;
310        }
311
312        if($id==null)
313            $id=param('id',param('iaid',param($this->table_info['pk_single_field'])));
314        $id = trim($id,"\t\r\n\0 }'\"\]:,;)");
315        $this->id=$id;
316        //$saveAndNew=param('iagNew',param('iagNew_x'))!='';
317        $this->esRetry=false;
318
319        // insert
320        if($h=='i') {
321            $this->insert_do();
322            $h=$this->h;
323            $id=$this->id;
324        }
325
326        // guardar
327        if($h=='s') {
328            $this->update_do();
329            $h=$this->h;
330        }
331
332        // presentar forma para alta
333        if($h=='a') {
334            return $this->form_alta_prepare();
335        }
336
337        //Borrar
338
339        // checa id y exista en la db
340        if($id=='') {
341            $this->msg_err.="<li>Error de transmision no llego el id del registro!";
342            $h=$this->h='msgerr';
343            $this->iaHeader_need_listme();
344            $this->iaHeader_need_form();
345            global $gWebDir;
346            $myFile = "C:\\wamp\\www\\$gWebDir\\backoffice\\txt\\error_id.txt";
347            $fh = fopen($myFile, 'w') or die("can't open file");
348            $bleh = "\r\n\r\nthis<pre>".print_r($this, true)."</pre>";
349            $bleh = "\r\n\r\npost<pre>".print_r($_POST, true)."</pre>";
350            $bleh = "\r\n\r\nget<pre>".print_r($_GET, true)."</pre>";
351            fwrite($fh, $bleh);
352            fclose($fh);
353            return false;
354        }
355
356        $this->enDB=$this->read_sql($id,$this->h);
357
358
359        if ($this->table !== 'producto_color_nuevo') {
360            if( array_key_exists($this->pk_field,$this->enDB) && $this->enDB[$this->pk_field]!=$id) {
361                $this->msg_err.="<li>Error de transmision no encontre el registro con id: ".ia_htmlentities($id);
362                $h=$this->h='msgerr';
363                $this->iaHeader_need_listme();
364                $this->iaHeader_need_form();
365                return false;
366            }
367        }
368
369        
370
371        // presentar forma para edit, read confirmar delete o delete
372        if($h=='e' || $h=='r' || $h=='b'  || $h=='d' ) {
373            $this->permiso_por_tabla($h,'',$this->enDB);
374            $this->permiso_por_record();
375            return $this->form_edit_view_delete_prepare();
376        } else
377            $this->iaHeader_need_listme();
378
379        $this->permiso_por_tabla($this->h,'',$this->enDB);
380        $this->permiso_por_campo($this->h,'',$this->enDB);
381;
382        return true;
383    }
384
385    /**
386     * iacase::process()
387     *
388     * @param string $h valor toca hacer normalmente param iah
389     * @param string $id
390     * @return
391     */
392    function process($h=null,$id=null) {
393        if($h==null)
394            $h=$this->h;
395        if($id==null)
396            $id=$this->id;
397
398        // checa permisos
399        if($this->h=='sinpermiso' || $h=='sinpermiso')
400            return $this->sin_permiso('sinpermiso');
401
402        if( ($h=='e' || $h=='s') && !$this->may_update() ) {
403            if(!$this->may_read())
404                return $this->sin_permiso($h);
405            $h=$this->h='r';
406        }
407
408        if( ($h=='a' || $h=='i') && !$this->may_insert() ) {
409            return $this->sin_permiso($h);
410        } elseif( ($h=='b' || $h=='d') && !$this->may_delete() ) {
411            return $this->sin_permiso($h);
412        } elseif( $h=='r'  && !$this->may_read() ) {
413            return $this->sin_permiso($h);
414        } elseif(!$this->may_list() ) {
415            return $this->sin_permiso($h);
416        }
417
418
419        if($h=='' || $this->modo=='jqgrid_form'  || $this->modo=='jqgrid_inline' ) {
420            return $this->listme();
421        }
422        if($h=='qbe')
423            return $this->qbe_forma();
424        elseif($h=='qbr')
425            return $this->qbe_resultados();
426        //else en qbenext y qbefield cambia la id al record equivalente
427        if($h=='e' || $h=='r' || $h=='b' || $h=='d')
428            if( $this->count_backoffice_view &&  array_key_exists('iac_pageviews',$this->campos) ) {
429                ia_query("UPDATE /* iacase:procesa */ $this->table SET iac_pageviews=iac_pageviews+1 WHERE $this->pk_field =".strit($this->id)." LIMIT 1");
430            }
431
432        if($h=='a')
433            return $this->forma_insert();
434        if($h=='e')
435            return $this->forma_update();
436        if($h=='r')
437            return $this->forma_read();
438        if($h=='b')
439            return $this->forma_delete_confirm();
440        if($h=='d')
441            return $this->forma_deleted_feedback();
442
443        return $this->listme();
444    }
445
446    /**
447     * iacase::iaHeader_need_listme()
448     *
449     * @return
450     */
451    function iaHeader_need_listme() {
452        global $gIaHeader;
453        $gIaHeader->html_head_add( array( 'jqgrid','ia') );
454    }
455
456    /**
457     * iacase::iaHeader_need_form()
458     *
459     * @param bool $RW
460     * @return
461     */
462    function iaHeader_need_form($RW=true) {
463        global $gIaHeader;
464        $gIaHeader->html_head_add( array( 'jqgrid') );
465        $need=array();
466        $this->iaHeader_need_has($need,'has_form_grid' );
467        if($RW || $this->modo=='jqgrid_iacform') {
468            if($this->useBlockUI)
469                $need[]='jquery.blockUI';
470            if($this->useJqueryValidate)
471                $need[]='jquery.validate';
472            $this->iaHeader_need_has($need,'has_date');
473            //$this->iaHeader_need_has($need,'has_anoMes');
474            //$this->iaHeader_need_has($need,'has_enum_set' );
475            $this->iaHeader_need_has($need,'has_datetime' );
476            $this->iaHeader_need_has($need, 'has_numeric');
477            $this->iaHeader_need_has($need,'has_child' );
478
479            $this->iaHeader_need_has($need,'has_file_upload' );
480            $this->iaHeader_need_has($need,'has_fckeditor');
481        }
482
483        $need[]='ia';
484        $gIaHeader->html_head_add( $need);
485    }
486
487    /**
488     * iacase::iaHeader_need_has()
489     *
490     * @param mixed $need
491     * @param string $h valor toca hacer normalmente param iahas
492     * @return
493     */
494     private function iaHeader_need_has(&$need,$has) {
495        if(array_key_exists($has,$this->table_info) && $this->table_info[$has] && !array_key_exists($has,$need) ) {
496
497            if($has=='has_numeric')
498                $need[]='auotNumeric';
499
500            if($has=='has_child')
501               ; // $need[]='table_addanother';
502            elseif($has=='has_form_grid')
503                $need[]='jqgrid';
504            if($has=='has_fckeditor')
505                $need[]='fckeditor';
506
507            elseif($has=='has_date') {
508                $need[]='datepicker'; // necesita para jqgrid aunque sea mobiscroll
509                if($this->input_date_widget=='mobiscroll')
510                    $need[]='mobiscroll';
511            }
512            elseif($has=='has_datetime' && $this->input_datetime_widget=='mobiscroll')
513                $need[]='mobiscroll';
514            elseif($has=='has_datetime')
515              ; //  $need[]='datetimepicker';
516            elseif($has=='has_time' && $this->input_time_widget=='mobiscroll')
517                $need[]='mobiscroll';
518            elseif($has=='has_time')
519                $need[]='datetimepicker';
520
521            elseif($has=='has_file_upload')
522                $need[]='jquery.MultiFile';
523        }
524    }
525
526
527    /**
528     * iacase::add_default_values()
529     *
530     * @param integer $addParams
531     * @return
532     */
533    function add_default_values($addParams=0) {
534        //FALTA $virtualCols o mejor a read_record
535        $this->enDB=ia_singletonFull("SELECT /* iacase:add_default_values h=a */ $this->cols_insert FROM $this->table WHERE $this->pk_field='-1' LIMIT 1");
536        $this->defaults_set($this->enDB);
537        $this->values=$this->enDB;
538        if($addParams == self::ADD_ALL_PARAMS)
539            $this->params_to_value();
540        elseif($addParams == self::ADD_ADHOC_PARAMS)
541            $this->add_adhoc_params();
542        return true;
543    }
544
545    /**
546     * iacase::add_adhoc_params()
547     *
548     * @return
549     */
550    function add_adhoc_params() {
551        return true;
552    }
553
554
555    /**
556     * iacase::params_to_value()
557     *
558     * @param bool $conOri
559     * @param bool $fillFromEnDB
560     * @param string $prefix
561     * @return
562     */
563    function params_to_value($conOri=true,$fillFromEnDB=false,$prefix='',$forzaRead=false) {
564        foreach($this->campos as $fieldName=>$f)
565            if( $f['modo']=='R/W' || $forzaRead || $this->array_val('hidden_value',$f,false)  ) {
566                if( $this->campo_key($fieldName,'numeric',false) ) {
567                    $tmp=$this->values[$fieldName]=str_replace( array(',','$','%','USD','MN','M.N.'),'',param($prefix.$fieldName));
568                    if( !$this->campo_key($fieldName,'Null',false) && $tmp==='' )
569                        $this->values[$fieldName]=0;
570                } elseif( $f['Type']=='datetime' && $this->input_datetime_widget=='datepicker' ) {
571                    $tmp=param($fieldName);
572                    //die($tmp);
573                    if($tmp!='')
574                        $this->values[$fieldName]=Date('Y-m-d G:i:s',strtotime($tmp)); //VCA
575                        //$this->values[$fieldName]=Date('Y-m-d G:i:s',$tmp);
576                } elseif( $this->campo_key($fieldName,'formato','')=='anoMes' ) {
577                    $tmp=param($prefix.'iaano_'.$fieldName).'/'.param($prefix.'iames_'.$fieldName);
578                    if($tmp=='/')
579                        $this->values[$fieldName]='';
580                    else
581                        $this->values[$fieldName]=$tmp;
582                } else
583                    $this->values[$fieldName]=param($prefix.$fieldName);
584                if($conOri)
585                    $this->ori[$fieldName]=param('ori_'.$fieldName);
586            } elseif($fillFromEnDB  && !array_key_exists($prefix.$fieldName,$_REQUEST) ) {
587                $this->values[$fieldName]=$this->enDB[$fieldName];
588            }
589    }
590
591////////////////////////////////////
592// VALIDATE
593///////////////////////////////////
594
595    /**
596     * iacase::validate_delete()
597     *
598     * @param array $record
599     * @return boolean TRUE continue, FALSE no permita el delete
600     */
601    function validate_delete($record) {
602    global $gAppRelate;
603
604        if($this->min_delete_id!=null) {
605            if(  $record[$this->pk_field]<=$this->min_delete_id ) {
606                $this->msg_err.="<li>Este registro no se puede borrar. Le ayuda cambiarle el nombre?";
607                return false;
608            }
609        }
610
611        if(!array_key_exists('links_from',$this->table_info))
612            return true;
613//echo "<p>1<P>2<pre>From ".print_r($this->table_info['links_from'],true)."<p>links to ".print_r($this->table_info['links_to'],true)."</pre>";
614
615        $ok=true;
616        if($this->table_info['links_from'])
617            foreach($this->table_info['links_from'] as $childTable=>$linkInfo) {
618              if(!empty($childTable) && !empty($linkInfo) && is_array($linkInfo))
619                    foreach($linkInfo as $from=>$info) if(!empty($from) && !empty($info) && is_array($info) ) {
620                        if( array_key_exists('restrict_delete',$info) && $info['restrict_delete']) {
621                            $hay=0;
622                            if($this->table!=$childTable && !is_string($record) && array_key_exists($this->pk_field, $record))
623                                $hay= ia_singleread( "SELECT /* iacase:validate_delete */ COUNT(*) FROM $childTable WHERE $from=".strit($record[$this->pk_field]) );
624                            else if(!is_string($record) && array_key_exists($this->pk_field, $record))
625                                $hay= ia_singleread( "SELECT /* iacase:validate_delete */ COUNT(*) FROM $childTable WHERE $from=".strit($record[$this->pk_field])." AND $this->pk_field<>".strit($this->id) );
626                            if($hay>0) {
627                                $this->msg_err.="<li>No se puede borrar, tiene ".number_format($hay,0,'',',')." ".to_label($childTable)." asociados";
628                                $ok=false;
629                            }
630                        }
631                }
632            }
633        return $ok;
634    }
635
636    /**
637     * iacase::validate()
638     *
639     * @return boolean true valido bien, false errores detectados
640     */
641    function validate() {
642    global $gAppRelate;
643        $ok=true;
644        foreach($this->campos as $fieldName=>$f) {
645        if( $f['modo']=='R/W' && ( (!$this->conOri || $this->h=='i') ||
646            ( $this->conOri && array_key_exists($fieldName,$this->values) && (!array_key_exists($fieldName,$this->ori) || $this->values[$fieldName]!=$this->ori[$fieldName]) )
647            )
648        ) {
649            // falta option dont validate
650            $this->campos[$fieldName]['conerror']='';
651            $type=array_val('Type',$f,'');
652            if( array_key_exists($fieldName,$this->values) )
653                $val=$this->values[$fieldName];
654            else
655                $val=null;
656            if( array_val('required',$f) && ($val=='' || ($val=='-0-0' && $type=='date') ) && $fieldName!=$this->pk_field &&  $type!='bit' ) {
657                $this->msg_err.="<li>".$this->label_field($fieldName)." es un dato requerido!";
658                $this->campos[$fieldName]['conerror']='Dato requerido.';
659                $ok=false;
660                continue;
661            }
662            if( $this->campo_key($fieldName,'UNI',false) && $this->campos[$fieldName]['UNI'] ) {
663                    $tmp=ia_singleread("SELECT /* iacase:validate unique */ COUNT(*) FROM $this->table WHERE $fieldName=".strit($val)." AND $this->pk_field <>".strit($this->id));
664                    if($tmp>0) {
665                        $this->msg_err.="<li>".$this->label_field($fieldName)." debe ser &uacute;nico, ya existe otro registro con el valor: "
666                            .ia_htmlentities($val).( array_key_exists($fieldName,$this->ori) && !empty($this->ori[$fieldName]) ? " <i>(el valor original era: ".$this->ori[$fieldName].")</i>" : '' );
667                        $ok=false;
668                        $this->campos[$fieldName]['conerror']='Hay otro con este valor.';
669                        continue;
670                    }
671            }
672            //
673            if( $this->campo_key($fieldName,'numeric',false) ) {
674                //$this->values[$fieldName]=$val=str_replace( array(',','$','%','USD','MN','M.N.'),'',$val ); ya se hizo!
675                //$this->values[$fieldName]=$val;
676                if($val==='' || $val===null)
677                    continue;
678                if(!is_numeric($val)) {
679                    $this->msg_err.="<li>".$this->label_field($fieldName)." debe ser n&uacute;merico!";
680                    $ok=false;
681                    $this->campos[$fieldName]['conerror']='Debe ser numero.';
682                    continue;
683                }
684                $max=$this->campo_key($fieldName,'max','');
685                if($max=='' && $this->campos[$fieldName]['Type']=='tinyint')
686                    if($this->campo_key($fieldName,'unsigned',false))
687                        $max=255;
688                    else
689                        $max=127;
690                if($max!='' && $val>$max) {
691                    $this->msg_err.="<li>".$this->label_field($fieldName).", su valor m&aacute;ximo es ".$max;
692                    $ok=false;
693                    $this->campos[$fieldName]['conerror']='Pasa de '.$max.'.';
694                    continue;
695                }
696                $min=$this->campo_key($fieldName,'min');
697                if($min!='' && $val<$min) {
698                    $this->msg_err.="<li>".$this->label_field($fieldName)." su valor m&iacute;nimo es ".$min;
699                    $ok=false;
700                    $this->campos[$fieldName]['conerror']='Abajo de '.$min.'.';
701                    continue;
702                }
703            }
704
705            if( $type=='date' ) {
706                if($val=='')
707                    continue;
708                if($val=='-0-0') {
709                    if($f['Null'])
710                        $this->values[$fieldName]=null;
711                    else
712                        $this->values[$fieldName]='0000-00-00';
713                    continue;
714                }
715                // is valid date
716                $tmp=explode('-',$val);
717                if(sizeof($tmp)!=3) {
718                    $this->msg_err.="<li>".$this->label_field($fieldName).", no es una fecha v&aacute;lida ";
719                    $ok=false;
720                    $this->campos[$fieldName]['conerror']='Fecha invalida.';
721                    continue;
722                }
723                //VCA
724                if($tmp[2] > 35)
725                {
726                    $this->values[$fieldName] = "$tmp[2]-$tmp[1]-$tmp[0]";
727                }
728
729                if(!@checkdate((int)$tmp[1],(int)$tmp[2],(int)$tmp[0])) {
730                    $this->msg_err.="<li>".$this->label_field($fieldName).", no es una fecha v&aacute;lida ";
731                    $ok=false;
732                    $this->campos[$fieldName]['conerror']='Fecha invalida.';
733                    continue;
734                }
735                $max=$min='';
736                //falta el problema es cual es la fecha de referencia!
737                $this->date_max_min($fieldName,$val,array(),$min,$max);
738                if($max!='' && $val>$max) {
739                    $this->msg_err.="<li>".$this->label_field($fieldName).", su valor m&aacute;ximo es $max";
740                    $ok=false;
741                    $this->campos[$fieldName]['conerror']='Mayor al permitido.';
742                    continue;
743                }
744                if($min!='' && $val<$min) {
745                    $this->msg_err.="<li>".$this->label_field($fieldName)." su valor m&iacute;nimo es $min";
746                    $ok=false;
747                    $this->campos[$fieldName]['conerror']='Menor al permitido';
748                    continue;
749                }
750            }
751            //email
752            //url
753            //string
754        }
755       }
756        if($ok && array_key_exists('UNI',$gAppRelate->tables[$this->table]) ) {
757            foreach($gAppRelate->tables[$this->table]['UNI'] as $indx=>$indxInfo) {
758
759                if(!empty($indxInfo) and is_array($indxInfo)) {
760
761                    $tmpWhere='';
762                    $tmpMsg='';
763                    foreach($indxInfo as $fieldName) {
764                        if( array_key_exists($fieldName,$this->values) )
765                            $val=$this->values[$fieldName];
766                        else
767                            $val=null;
768                        $tmpWhere.=" AND $fieldName=".strit($val);
769                        $tmpMsg.=", ".$this->label_field($fieldName);
770                    }
771                    $tmpWhere=substr($tmpWhere,4);
772                    $tmpMsg=substr($tmpMsg,2);
773
774                    $tmp=ia_singleread("SELECT /* iacase:validate unique */ COUNT(*) FROM $this->table WHERE $tmpWhere AND $this->pk_field <>".strit($this->id));
775                    if($tmp>0) {
776                        $this->msg_err.="<li>$tmpMsg deben ser &uacute;nicos, ya existe otro registro con esos valores: ";
777                        $ok=false;
778                        //foreach($indxInfo as $fieldName)
779                            //$this->campos[$fieldName]['conerror']='Hay otro con este valor.';
780                    }
781                }
782            }
783        }
784
785
786
787        return $ok;
788    }
789
790////////////////////////////////////
791// INSERT
792///////////////////////////////////
793
794    /**
795     * iacase::insert_do()
796     * Checa permiso para insert, llama insert que valida y hace insert y pone el siguiente paso
797     * @return boolean false no tiene permiso para insertar
798     */
799    public function insert_do() {
800        $this->params_to_value(false,false);
801        if(!$this->may_insert()) {
802            $this->msg_err.="<li>No tiene permiso de dar altas";
803            $h=$this->h='sinpermiso';
804            return false;
805        }
806
807        $this->id=param('iaid',$this->id);
808        $saveAndNew=param('iagNew',param('iagNew_x'))!='';
809        $this->values[ $this->pk_field ]=$this->id;
810        if ($this->insert()) {
811            if($saveAndNew) {
812                $this->msg_aviso.="<li>Nueva alta";
813                $h=$this->h='a';
814
815            } else {
816                $id=$this->id;
817                $h='e';
818                $this->h=$h;
819                $this->h_next='s';
820                // recalcula permisos, algunos app lo traen en private!
821                if(in_array('campos_final',get_class_methods($this)))
822                    $this->campos_final();
823            }
824        } else {
825            $this->esRetry=true;
826            $h=$this->h='a';
827            $this->h_next='i';
828        }
829        return true;
830    }
831    /**
832     * iacase::insert()
833     * Llama la sequencia para hacer un insert: validar, hacer el save, post save
834     * @return boolean false ho funciono el insert. true se hizo el insert
835     */
836    public function insert() {
837        if(!$this->insert_pre_validate())
838            return false;
839
840        if(!$this->insert_validate())
841            return false;
842
843        if(!$this->insert_pre_save())
844            return false;
845        $log='';
846        if(!$this->insert_save())
847            return false;
848
849        $this->insert_post_save();
850
851        $this->msg_aviso.="<li>Alta realizada!";
852        $this->log('insert',$log );
853        return true;
854    }
855
856    /**
857     * iacase::insert_pre_validate()
858     * Tip si no pasa validacion llenar $this->msg_error.="<li>..."  para avisar al usuario
859     * @return boolean true pre validacion ok; continua con validacion default. false no paso la validacion no se hace el insert
860     */
861    function insert_pre_validate()  { return true; }
862
863    /**
864     * iacase::insert_validate()
865     * Valida el insert por default llama $this->validate para la validacion default: tipos, limites max/min, longitud y uniques.
866     * Tip si no pasa validacion llenar $this->msg_error.="<li>..."
867     * @return boolean true validacion ok, false
868     */
869    function insert_validate()  { return $this->validate(); }
870
871    /**
872     * iacase::insert_pre_save()
873     * Tip si no pasa llenar $this->msg_error.="<li>..." para avisar al usuario
874     * @return boolean true all ok continua. false deten el insert
875     */
876    function insert_pre_save()  { return true; }
877
878    /**
879     * iacase::insert_extra_values()
880     * permite agregar valores al insert sql statement o modificar el array del que hacer el insert
881     * @param string $insArray  agregar insert clause, terminar con coma ie: $ins.=",campo1"
882     * @param string $log   agregar o cambiar el log
883     * @return boolean TRUE continua con el isnert, FALSE cancela el insert en este caso avisar en $this->msg_err.="<li>explica..."
884    */
885    function insert_extra_values(&$insArray,&$log) { return true; }
886
887    /**
888     * iacase::insert_extra_sql() OBSOLETE DELETEME
889     * permite agregar valores al insert sql statement agregando al inicio del insert clause y su equivalente values clause
890     * OJO usar .= $ins.=",campo1" $val.="valor_campo," LAS COMAS VAN $ins al incio y $val al final!
891     * @param string $ins  agregar insert clause, terminar con coma ie: $ins.=",campo1"
892     * @param string $val  agregar valores del value clause terminar con coma ie: $val.="valor_campo1,"
893     * @return void
894    */
895    function insert_extra_sql(&$ins,&$val,&$log) { }
896
897    /**
898     * iacase::insert_add_sql_queries()
899     * permite agregar queries al transaction del insert
900     * Tipo de regresar false llenar  $this->msg_err
901     * @param array $sql  agregar queries al array $sql[]="";
902     * @param string $log  agregar info al log $log.="<li>.."
903     * @return boolean true continuar, false no continuar - no se hace el insert
904    */
905    function insert_add_sql_queries(&$sql,&$log) { return true;}
906
907    /**
908     * iacase::insert_save()
909     * Guarda el registro, sus childs y crea workflows en su caso
910     * @return boolean true ok, false error al guardar
911     */
912    function insert_save() {
913    global $gAppRelate;
914    global $gIAsql;
915    global $gSqlClass;
916    $gIAsql['trace']=$gSqlClass->traceOn=true;
917        $log='';
918        if($this->table_info['pk_single_type']=='auto_increment') {
919            $findId=$this->table_info['pk_single_type']=='auto_increment';
920            $key='getID_insert_main_record';
921        } else {
922            $findId=0;
923            $key=0;
924        }
925        $sql[$key]=$this->insert_sql($log);
926        if(empty($sql[$key])) {
927            $this->msg_err="<li>No hay datos que guardar!";
928            return false;
929        }
930        if(!$this->insert_add_sql_queries($sql,$log))
931            return false;
932
933        if( ia_transaction($sql,"iacase:insert_save $this->table",$findId) ) {
934            $this->msg_err="<li>Error al guardar ";
935            return false;
936        }
937
938        if($findId) {
939
940            $this->values[$this->pk_field]=$this->id=array_key_exists('last_id',$gIAsql)?$gIAsql['last_id']:0;
941            /**
942            echo "<pre>".print_r($gIAsql, true)."</pre>";
943            echo "<pre>".print_r($sql, true)."</pre>";
944            echo "<pre>".print_r($this->values, true)."</pre>";
945            echo "<pre>".print_r($gSqlClass, true)."</pre>";die();
946            **/
947        }
948
949        // sequences diferentes a insert_value
950        if(!empty($this->table_info['has_seq'])) {
951            foreach($this->table_info['has_seq'] as $sF=>$seq)
952                if( !array_key_exists('insert_value',$seq) || empty($seq['insert_value']) ) if($this->campos[$sF]['modo']!='R/W' || empty($this->values[$sF])) {
953                    // deduce el prefijo
954                    $prefijo=$this->array_val('prefijo',$seq);
955                    if(empty($prefijo)) {
956                        $tmpField=$this->array_val('prefijoField',$seq);
957
958                        if(!empty($tmpField)) {
959                            if( array_key_exists('link_table',$this->campos[$tmpField]) ) {
960                                $prefijo=ia_singleread ($gAppRelate->sql_link_read( $this->campos[$tmpField]['link_table'] ,$tmpField,$this->values[$tmpField]));
961
962                            } else
963                                $prefijo=$this->values[$tmpField];
964                        }
965                    }
966
967                    // obten numero
968                    $tmpOk=true;
969                    if( array_val('tipo',$seq)=='seqid' ) {
970                        $seqnum=$this->id;
971                        if(  ($pad=$this->array_val('pad',$seq,0)) )
972                            $seqnum=str_pad($seqnum,$pad,'0',STR_PAD_LEFT);
973                        if( ia_query("UPDATE $this->table SET $sF=".strit($prefijo.$seqnum)." WHERE $this->pk_field=".$this->id." LIMIT 1"  ) ) {
974                                $tmpOk=false;
975                        }
976                    } elseif( array_val('tipo',$seq)=='seqphp' ) {
977                        ia_begin();
978                        $seqnum=ia_singleread("SELECT val FROM iac_seq WHERE name=".strit($prefijo)." FOR UPDATE",0,false,false);
979                        if($seqnum!==FALSE) {
980                            $seqnum++;
981                            if( ia_query("INSERT iac_seq(name,val) VALUES(".stritc($prefijo).$seqnum.') ON DUPLICATE KEY UPDATE val='.strit($seqnum) )) {
982                                $tmpOk=false;
983                            } else {
984                                if(  ($pad=$this->array_val('pad',$seq,0)) )
985                                    $seqnum=str_pad($seqnum,$pad,'0',STR_PAD_LEFT);
986                                if( ia_query("UPDATE $this->table SET $sF=".strit($prefijo.$seqnum)." WHERE $this->pk_field=".$this->id." LIMIT 1"  ) ) {
987                                    $tmpOk=false;
988                                } else
989                                    $this->values[$sF]=$prefijo.$seqnum;
990                            }
991                        } else
992                            $tmpOk=false;
993
994                        if($tmpOk) {
995                            ia_commit();
996                        } else
997                            ia_rollback();
998                    } else {
999                        $seqnum=$this->id;
1000                        if( ia_query("UPDATE $this->table SET $sF=".strit($prefijo.$seqnum)." WHERE $this->pk_field=".$this->id." LIMIT 1"  ) ) {
1001                                $tmpOk=false;
1002                        } else
1003                            $this->values[$sF]=$prefijo.$seqnum;
1004                    }
1005                  // FALTA Log entry de asignacion del numero?
1006                }
1007        } // end if sequences
1008
1009        $sql=array();
1010        $this->child_table_save_all($sql,$log);
1011        if( !empty($sql) )
1012            ia_transaction($sql);
1013
1014        $sql=array();
1015        $this->files_upload($this->id,$sql,$log);
1016        if( !empty($sql) )
1017            ia_transaction($sql);
1018
1019        if($log!='')
1020            $this->log('insert',$log);
1021
1022        // trigger workflows
1023        if($gAppRelate->has_workflow) {
1024            $workflow=new iaworkflow();
1025            $workflow->trigger_document_alta($this,$this->values);
1026        }
1027        return true;
1028    }
1029
1030    /**
1031     * iacase::insert_post_save()
1032     *
1033     * @return
1034     */
1035    function insert_post_save()   {return true;}
1036
1037////////////////////////////////////
1038// UPDATE
1039///////////////////////////////////
1040    /**
1041     * iacase::update_do()
1042     *
1043     * @return boolean true ok, false no paso el update
1044     */
1045    function update_do() {
1046
1047        $h=$this->h;
1048        $id=$this->id;
1049        $saveAndNew=param('iagNew',param('iagNew_x'))!='';
1050
1051        //$virtualCols='';
1052        //foreach($this->campos as $fieldName=>$f) if( array_key_exists('virtual_sql', $this->campos[$fieldName]) )
1053        //    $virtualCols.=','.$this->campos[$fieldName]['virtual_sql'];
1054        //$this->enDB=ia_singletonFull("SELECT /* iacase:process_action */ *$virtualCols FROM $this->table WHERE $this->pk_field=".strit($id)." LIMIT 1",'');
1055        $this->enDB=$this->read_sql($id);
1056
1057
1058        $this->permiso_por_tabla($h,'',$this->values);
1059        $this->permiso_por_campo($h,'',$this->values);
1060        $this->permiso_por_record();
1061
1062
1063        
1064        $this->params_to_value(true,false);
1065
1066        if(!$this->may_update()) {
1067            $this->msg_err.="<li>No tiene permiso de editar";
1068            $h=$this->h='sinpermiso';
1069            return false;
1070        }
1071
1072        if ($this->update()) {
1073            if($saveAndNew && $this->may_add() ) {
1074                $this->msg_aviso.="<li>Nueva alta";
1075                $h=$this->h='a';
1076                $this->h_next='i';
1077            } else {
1078                if($this->modo=='jqgrid_iacform') {
1079
1080                }
1081                //$this->enDB=ia_singletonFull("SELECT /* iacase:process_action */ *$virtualCols FROM $this->table WHERE $this->pk_field=".strit($id)." LIMIT 1",'');
1082                $this->enDB=$this->read_sql($id);
1083                $h=$this->h='e';
1084                $this->h_next='s';
1085            }
1086            return true;
1087        } else {
1088            $this->esRetry=true;
1089            $h=$this->h='e';
1090            $this->h_next='s';
1091            return false;
1092        }
1093
1094    }
1095
1096    /**
1097     * iacase::update()
1098     *
1099     * @return boolean true ok, false no paso el update
1100     */
1101    function update() {
1102    global $gAppRelate;
1103
1104        if(!$this->update_pre_validate())
1105            return false;
1106
1107        if(!$this->update_validate())
1108            return false;
1109
1110        if(!$this->update_pre_save())
1111            return false;
1112
1113        if(!$this->update_save())
1114            return false;
1115
1116        // trigger workflows
1117        if($gAppRelate->has_workflow && !empty($this->changedMainTable)) {
1118            $workflow=new iaworkflow();
1119            $workflow->trigger_document_guarda($this,$this->changedMainTable);
1120        }
1121        return $this->update_post_save();
1122
1123    }
1124
1125    /**
1126     * iacase::update_pre_validate()
1127     *
1128     * @return
1129     */
1130    function update_pre_validate()  { return true; }
1131
1132    /**
1133     * iacase::update_validate()
1134     *
1135     * @return
1136     */
1137    function update_validate()  { return $this->validate(); }
1138
1139    /**
1140     * iacase::update_pre_save()
1141     *
1142     * @return
1143     */
1144    function update_pre_save()  { return true; }
1145
1146    /**
1147     * iacase::update_add_sql_queries()
1148     * permite agregar queries al transaction del update
1149     * Tipo de regresar false llenar  $this->msg_err
1150     * @param array $sql  agregar queries al array $sql[]="";
1151     * @param string $log  agregar info al log $log.="<li>.."
1152     * @return boolean true continuar, false no continuar - no se hace el insert
1153    */
1154    function update_add_sql_queries(&$sql,&$log) { return true;}
1155
1156    /**
1157     * iacase::update_extra_sql()
1158     * permite agregar valores al update sql
1159     * @param string $updArray  array de valores
1160     * @param string $log  agregar <li> al log ie: $log.="<li>..."
1161     * @return boolean TRUE continua con el update FALSE no hace el update poner mensaje en $this->msg_err.="<li>..."
1162    */
1163    function update_extra_sql(&$updArray,&$log) { return true; }
1164
1165    /**
1166     * iacase::update_save()
1167     *
1168     * @return
1169     */
1170    function update_save() {
1171        $log='';
1172
1173        $sqlupd=$this->update_sql($log);
1174        // dd_($sqlupd);
1175        $sql=array();
1176        if($sqlupd!='') {
1177            if (is_array($sqlupd))
1178                $sql=$sqlupd;
1179            else
1180                $sql[]=$sqlupd;
1181        }
1182            
1183
1184        $sql_child_table_save_all = $this->child_table_save_all($sql,$log);
1185        if (!empty($sql_child_table_save_all))
1186            $sql[]=$sql_child_table_save_all;
1187        $this->files_upload($this->id,$sql,$log);
1188
1189        if(!$this->update_add_sql_queries($sql,$log))
1190            return false;
1191
1192        if(empty($sql)) {
1193            $this->msg_aviso.="<li>Sin cambios!";
1194            return true;
1195        }
1196
1197        if(  ia_transaction($sql) ) {
1198            $this->msg_err="<li>Error al guardar ";
1199            return false;
1200        }
1201
1202        if($log!='')
1203            $this->log('update',$log);
1204        $this->msg_aviso.="<li>Datos guardados!";
1205        return true;
1206    }
1207
1208    /**
1209     * iacase::update_post_save()
1210     *
1211     * @return
1212     */
1213    function update_post_save()   {return true;}
1214
1215////////////////////////////////////
1216// DELETE
1217///////////////////////////////////
1218    function delete_do($solo_response = false) {
1219        $h=$this->h;
1220        $id=$this->id;
1221        if(!$this->may_delete()) {
1222            $this->msg_err.="<li>No tiene permiso de borar";
1223            $h=$this->h='sinpermiso';
1224            return false;
1225        }
1226        // validate delete
1227        if(!$this->delete_pre_validate($h)) {
1228            $this->h='r';
1229            return false;
1230        } if(!$this->validate_delete($this->values)) {
1231            $this->h='r';
1232            return false;
1233        }
1234        if(!$this->delete_post_validate($h)) {
1235            $this->h='r';
1236            return false;
1237        }
1238        if($h=='b') {
1239            if(!$this->delete_pre_confirm_delete())
1240                return false;
1241            $this->msg_aviso.="<li>Confirme borrar el registro <br/>".ia_htmlentities($this->label_record_summary());
1242            $this->h_next='d';
1243
1244        } elseif($h=='d') {
1245            if(!$this->delete_pre_delete($h))
1246                return false;
1247            $sql=$this->delete_sql($this->values);
1248            $this->delete_sql_extra($this->values,$sql);
1249            // dd_($sql);
1250            if( ia_transaction($sql)) {
1251                $this->msg_err.="<li>Error al borrar el registro: ".ia_htmlentities($this->label_record());
1252                $h=$this->h='r';
1253                $this->h_next='r';
1254                return false;
1255            } else {
1256                $this->msg_aviso.="<li>Registro eliminado:<br/>".ia_htmlentities($this->label_record_summary());
1257
1258
1259                //$h=$this->h=$this->h_next='';
1260                $this->log('delete',ia_htmlentities($this->label_record_summary()));
1261                $cardex_grid=param('iagridvar', 'gridhandler');
1262                if(!empty($cardex_grid)) {
1263                  $this->jsscripts .= "<script>
1264                  try {
1265                        //console.log('window.opener.$cardex_grid: ' + window.opener.$cardex_grid);
1266//                        window.opener.$cardex_grid.trigger('reloadGrid');
1267                        iac_cardex_window_close('SI');
1268                        
1269                    } catch(er) {console.log('refreshing parent window grid',er)}
1270//                    setTimeout(function(){ closewin(); },0);
1271                    
1272                    </script>";
1273                }
1274
1275                if (false && !$solo_response) {
1276                    echo $this->jsscripts;
1277                }
1278                //$this->jsscripts = '';
1279
1280            }
1281            $post_delete =  $this->delete_post_delete($h);
1282            if ($post_delete == null)
1283                return true;
1284
1285            if (!$post_delete)
1286                return false;
1287            /* if(!$this->delete_post_delete($h))
1288                return false; */
1289        }
1290        return true;
1291    }
1292    /**
1293     * iacase::delete_pre_validate()
1294     *
1295     * @param string $h valor toca hacer normalmente param iah
1296     * @return boolean true pasa validacion borrar, false no pasa
1297     */
1298    function delete_pre_validate($h) { return true; }
1299
1300    /**
1301     * iacase::delete_post_validate()
1302     *
1303     * @param string $h valor toca hacer normalmente param iah
1304     * @return boolean true continua, false no permite
1305     */
1306    function delete_post_validate($h) { return true; }
1307
1308    /**
1309     * iacase::delete_pre_confirm_delete()
1310     *
1311     * @return boolean true continua, false no permite
1312     */
1313    function delete_pre_confirm_delete() { return true; }
1314
1315    /**
1316     * iacase::delete_pre_delete()
1317     *
1318     * @param string $h valor toca hacer normalmente param iah
1319     * @return boolean true continua, false no permite
1320     */
1321    function delete_pre_delete($h) { return true; }
1322
1323    /**
1324     * iacase::delete_post_delete()
1325     *
1326     * @param string $h valor toca hacer normalmente param iah
1327     * @return void
1328     */
1329    function delete_post_delete($h) {  }
1330
1331    /**
1332     * iacase::delete_sql()
1333     *
1334     * @param string $record record values to delete, normalmente $this->values
1335     * @return array con sql deletes necesarios
1336     */
1337    function delete_sql($record) {
1338        $sql=array();
1339        if(array_key_exists('links_from',$this->table_info)) {
1340            if($this->table_info['links_from'])
1341                foreach($this->table_info['links_from'] as $childTable=>$linkInfo)
1342                   if(!empty($linkInfo) && is_array($linkInfo)) foreach($linkInfo as $from=>$info) if( !empty($info) && is_array($info)) {
1343                        if( !array_key_exists('restrict_delete',$info) || !$info['restrict_delete'])
1344                            if(array_key_exists('delete_with_parent',$info) && $info['delete_with_parent']&& !is_string($record) && array_key_exists($this->pk_field, $record))
1345                                $sql[]=  "DELETE /* iacase:delete_sql child */ FROM $childTable WHERE $from=".strit($record[$this->pk_field]);
1346                    }
1347        }
1348        $sql[]="DELETE /* iacase:delete_sql record */ FROM $this->table WHERE $this->pk_field=".strit($record[$this->pk_field]);
1349        return $sql;
1350    }
1351
1352    /**
1353     * iacase::delete_sql()
1354     *
1355     * @param string $record record values to delete, normalmente $this->values
1356     * @param array $sql array de sql commands al que agregar queries
1357     * @return void
1358     */
1359    function delete_sql_extra($record,&$sql) {
1360
1361    }
1362
1363    function export_record() {
1364        $this->msg_err.="<li>Export not programmed";
1365    }
1366
1367////////////////////////////////////
1368// LOG
1369///////////////////////////////////
1370
1371    /**
1372     * iacase::log_field()
1373     *
1374     * @param string $fieldName nombre del campo
1375     * @param mixed $msg
1376     * @param mixed $log
1377     * @return void
1378     */
1379    function log_field($fieldName,$msg,&$log) {
1380        $log.='<li><b>'.$fieldName.'</b>: '.$msg;
1381    }
1382
1383    /**
1384     * iacase::log()
1385     *
1386     * @param mixed $action
1387     * @param mixed $log
1388     * @return
1389     */
1390    public function log($action,$log,$para=null) {
1391    global $gAppRelate;
1392
1393        $id=$this->id;
1394        if($para===null)
1395            if($this->h=='s')
1396                $para='Cambia ';
1397            elseif($this->h=='e')
1398                $para='Edita ';
1399            elseif($this->h=='i')
1400                $para='Agrega ';
1401            elseif($this->h=='a')
1402                $para='Edita alta';
1403            elseif($this->h=='r')
1404                $para='Consulta ';
1405            elseif($this->h=='b')
1406                $para='Consulta para borrar';
1407            elseif($this->h=='d')
1408                $para='Borra ';
1409
1410       if($this->h=='i' || $id!='')
1411           $log =$para.$this->label.": ".ia_htmlentities( $this->label_record_summary() )."<ul>".$log."</ul>";
1412        $gAppRelate->log($action,$this->table,$id,$log,$this->usuario,ia_htmlentities($this->label_record_summary() ) );
1413    }
1414
1415////////////////////////////////////
1416// SHOW AVISOS AND ERROR MESSAGES
1417///////////////////////////////////
1418    /**
1419     * iacase::msg_show()
1420     *
1421     * @return
1422     */
1423    function msg_show() {
1424        if(!empty($this->msg_err)) {
1425            //VCA 18-06-2020 Ponemos un vx_alert para que el usuario vea que hay un error.
1426            //echo "<div class=msgerr><ul>$this->msg_err</ul></div>";
1427            echo "<script>$(function () {vx_alert_error('IA_ERROR_','<ul>$this->msg_err</ul>','Error');})</script>";
1428            //$this->msg_err='';
1429        }
1430        /*if(!empty($this->msg_aviso)) {
1431            echo "<div class='msgaviso'><ul>$this->msg_aviso</ul></div>";
1432            if($this->h != 'b' && $this->h != 'd')
1433                echo "<script>setTimeout(function(){ $('.msgaviso').hide(); },2000);</script>";
1434            $this->msg_aviso='';
1435        }*/
1436    }
1437
1438////////////////////////////////////
1439// FORMS EDIT, INSERT, VIEW
1440///////////////////////////////////
1441
1442    function form_edit_view_delete_prepare() {
1443            if(!$this->esRetry)
1444                $this->values=$this->enDB; //  ia_singletonFull("SELECT *$virtualCols FROM $this->table WHERE $this->pk_field=".strit($this->id)." LIMIT 1",'');
1445            else
1446                $this->values[$this->pk_field]=$this->enDB[$this->pk_field]??'';
1447
1448            if ($this->table !== 'producto_color_nuevo') {
1449                if(($this->values[$this->pk_field]??'')!=$this->id) {
1450                    $this->msg_err.="<li>Error de transmision no encontre el registro con id: ".ia_htmlentities($this->id);
1451                    $this->h='msgerr';
1452                    return false;
1453                }
1454            }
1455            
1456            // presentar forma para editar
1457            if( $this->h=='e'  && !$this->may_edit() && $this->may_read())
1458                $this->h='r';
1459            if($this->h=='e') {
1460                if(!$this->may_edit()) {
1461                    $this->msg_err.="<li>No tiene permiso de editar";
1462                    $this->h='sinpermiso';
1463                    return false;
1464                }
1465                $this->iaHeader_need_form();
1466                $this->ori= $this->enDB;
1467                $this->h_next='s';
1468            } else
1469                $this->iaHeader_need_form(false);
1470
1471            // pide delete, delete, read record
1472            if($this->h=='b' || $this->h=='d') {
1473                if($this->may_delete())
1474                    return $this->delete_do();
1475                $this->msg_err.="<li>Sin permiso de borrar!";
1476                $this->h='r';
1477            }
1478
1479            // consultar el record
1480            if($this->h=='r') {
1481                if(!$this->may_read()) {
1482                    $this->msg_err.="<li>No tiene permiso de consultar";
1483                    $this->h='sinpermiso';
1484                    return false;
1485                }
1486                return true;
1487            }
1488            return true;
1489    }
1490
1491    function form_alta_prepare() {
1492            $this->iaHeader_need_form(); //VCA para que sea bien el toolbar y todo.
1493
1494            if( !$this->may_add() ) {
1495                $this->msg_err.="<li>No tiene permiso de dar altas";
1496                $this->h='sinpermiso';
1497                return false;
1498            }
1499
1500            $this->h_next='i';
1501            if($this->esRetry)
1502                $this->add_default_values(self::ADD_ALL_PARAMS);
1503            else {
1504                $this->add_default_values(self::ADD_ADHOC_PARAMS);
1505                $this->id='';
1506            }
1507            if( $this->table_info['pk_single_type']=='uuid' ) {
1508                if($this->esRetry) {
1509                    $this->id=param('iaid', param('id'));
1510                } else {
1511                    if(array_key_exists('pk_single_type_iauid', $this->table_info))
1512                        $this->id=ia_singleread("SELECT MAX(iac_usr_id)+1 as iac_usr_id FROM iac_usr");
1513                    else
1514                        $this->id=ia_guid("iacase:process_action $this->table");
1515                }
1516            }
1517
1518            $this->enDB[ $this->pk_field ]= $this->values[ $this->pk_field ]=$this->id;
1519            return true;
1520    }
1521    /**
1522     * iacase::form_tag()
1523     *
1524     * @param string $action
1525     * @param string $tag
1526     * @param mixed $extraParams
1527     * @return
1528     */
1529    function form_tag($action='',$tag='novalidate',$extraParams=array()) {
1530    $useJqueryValidate=$this->useJqueryValidate && ($this->h=='e' || $this->h=='a' || $this->h=='s' || $this->h=='i');
1531    $useFormChanged=$this->useFormChanged && ($this->h=='e' || $this->h=='a' || $this->h=='s' || $this->h=='i');
1532    $useBlockUI=$this->useBlockUI && ($this->h=='e' || $this->h=='a' || $this->h=='s' || $this->h=='i');
1533    if($useJqueryValidate || $useFormChanged || $useBlockUI)
1534        $javascript="<script>\$(function($){\$('#$this->formId').iaFormControl(".($useJqueryValidate ? 'true,' : 'false,').($useFormChanged ? 'true,' : 'false,').($useBlockUI ? 'true' : 'false')."); "
1535.($useJqueryValidate ? "var validator=$('#$this->formId').validate( {debug:false, ignore: '.ignore-val',meta: 'validate' } );" : '')."});</script>";
1536
1537
1538
1539
1540    else
1541        $javascript='';
1542
1543        if($action=='')
1544            $action=$_SERVER['PHP_SELF'];
1545
1546        //VCA Cheque DD
1547        if((property_exists($this, "CDD") && $this->CDD == 'SI') || $this instanceof app_cheque_dd)
1548            $action = str_replace("cheque.php", "cheque_dd.php", $action);
1549
1550
1551        $param_iah='';
1552        if($this->h_next === 'i' || $this->h_next === 's' ) {
1553            $param_iah = '?iah='.$this->h;
1554            $param_iah .= "&id=$this->id";
1555        }
1556
1557        if (str_contains($action, 'javascript'))
1558            $param_iah = "";
1559
1560        $params='';
1561        if($extraParams) foreach($extraParams as $k=>$d)
1562            $params .= "<input type=hidden name='$k' id='$k' value='$d'/>";
1563        if($this->extraParams) foreach($this->extraParams as $k=>$d)
1564            $params.="<input type=hidden name='$k' id='$k' value='$d'/>";
1565        $cardex_grid=param('iagridvar');
1566        if(!empty($cardex_grid)) {
1567            $params .= "<input type=hidden name='iagridvar' id='iagridvar' value='$cardex_grid'/>";
1568//            $param_iah .= "&iagridvar=$cardex_grid";
1569//            if($this->h_next === 'i')
1570//                $param_iah .= "&iarowindex=1&iarn1=1&iarnL=1&iarnA=1";
1571        }
1572        return PHP_EOL.$javascript
1573           .PHP_EOL."<form id='$this->formId' method='POST' enctype='multipart/form-data' action='$action$param_iah$tag><input type=hidden name='iah' id='iah' value='$this->h_next'/><input type=hidden name='id' id='id' value='$this->id'/><input type=hidden name='iaid' id='iaid' value='$this->id'/>$params<input type=hidden name='iacc' id='iacc' value='".get_class($this)."'/>";
1574
1575
1576
1577    }
1578
1579    /**
1580     * iacase::forma_insert()
1581     *
1582     * @param string $nexth
1583     * @return
1584     */
1585    function forma_insert($nexth='i') {
1586       $ok=$this->forma('a',$nexth);
1587       return $ok;
1588    }
1589
1590    /**
1591     * iacase::forma_update()
1592     *
1593     * @param string $nexth
1594     * @return
1595     */
1596    function forma_update($nexth='s') {
1597       $ok=$this->forma('s',$nexth);
1598       return $ok;
1599    }
1600
1601    /**
1602     * iacase::forma_read()
1603     *
1604     * @param string $h
1605     * @return
1606     */
1607    function forma_read($h='r') {
1608       $ok=$this->forma($h);
1609       return $ok;
1610    }
1611
1612    /**
1613     * iacase::forma_delete_confirm()
1614     *
1615     * @param string $h
1616     * @return
1617     */
1618    function forma_delete_confirm($h='b') {
1619       $ok=$this->forma($h,'d');
1620       return $ok;
1621    }
1622
1623    /**
1624     * iacase::forma_deleted_feedback()
1625     *
1626     * @return
1627     */
1628    function forma_deleted_feedback() {
1629        return true;
1630    }
1631
1632    /**
1633     * iacase::forma()
1634     *
1635     * @param string $h valor toca hacer normalmente param iah
1636     * @param string $nexth
1637     * @return
1638     */
1639    public function forma($h,$nexth='') {
1640        if(!$this->forma_pre($h,$nexth))
1641            return false;
1642
1643        if( $this->formType=='deduce')
1644            $ok= $this->forma_deduce($h,$nexth);
1645        elseif( $this->formType=='sequencial')
1646            $ok= $this->forma_sequencial($h,$nexth);
1647        return $ok;
1648
1649    }
1650
1651    /**
1652     * iacase::forma_pre()
1653     *
1654     * @param string $h valor toca hacer normalmente param iah
1655     * @param string $nexth
1656     * @return
1657     */
1658    public function forma_pre(&$h,&$nexth) { return true; }
1659
1660    /**
1661     * iacase::forma_post()
1662     *
1663     * @param string $h valor toca hacer normalmente param iah
1664     * @param string $nexth
1665     * @param boolean $ok si el presentador de la forma regreso true o false
1666     * @return
1667     */
1668    public function forma_post(&$h,&$nexth,$ok=true) { return true; }
1669
1670    /**
1671     * iacase::forma_preFields()
1672     *
1673     * @param string $h valor toca hacer normalmente param iah
1674     * @param string $nexth
1675     * @return
1676     */
1677    public function forma_preFields(&$h,&$nexth) { return true; }
1678    /**
1679     * iacase::forma_postFields()
1680     *
1681     * @param string $h valor toca hacer normalmente param iah
1682     * @param string $nexth
1683     * @return
1684     */
1685    public function forma_postFields(&$h,&$nexth) { return true; }
1686
1687    /**
1688     * iacase::forma_doChilds()
1689     *
1690     * @param string $h valor toca hacer normalmente param iah
1691     * @param string $nexth
1692     * @return
1693     */
1694    public function forma_doChilds(&$h,&$nexth) { return true; }
1695    /**
1696     * iacase::forma_post()
1697     *
1698     * @param string $h valor toca hacer normalmente param iah
1699     * @param string $nexth
1700     * @return FALSE no hagas los childs en automatico, si lo demas. TRUE haz los childs en automatico
1701     */
1702
1703
1704    /**
1705     * iacase::forma_postDiv()
1706     *
1707     * @param string $h valor toca hacer normalmente param iah
1708     * @param string $nexth
1709     * @return void
1710     */
1711    public function forma_postDiv($h,$nexth) {
1712        //Solo en grid no ponemos el botón de cerrar.
1713        echo <<<FACTIONS
1714<script>
1715    closeItem = iac_cardex_window_close;
1716    _app_local = '$this->table';
1717    
1718    \$vitex_globales['init_ia_jqueries_sincrono'] = true;
1719    \$vitex_globales['init_ia_jqueries_corre_inicio'] = true;
1720</script>
1721
1722<div id="IA_ERROR_" class="ui-state-error ui-corner-all" style="display:none; padding: 0 .7em;"></div>
1723<div id="IA_PRINT_DOC" style="display:none;"></div>
1724FACTIONS;
1725
1726        if($h=='e' || $h=='s' || $h=='a' || $h=='i')
1727            echo <<<FACTIONS
1728<script>
1729
1730    saveItem = guardaDocumentoPadre;
1731    //$(document).ready(function(){ $("#$this->formId").validationEngine(); });
1732</script>
1733FACTIONS;
1734
1735    }
1736
1737    /**
1738     * iacase::forma_miniLog()
1739     *
1740     * @param string $h valor toca hacer normalmente param iah
1741     * @param string $h valor toca hacer normalmente param iahasMini
1742     * @return void
1743     */
1744    public function forma_miniLog($h,$hasMini) {
1745        if($hasMini['logins'] || $hasMini['log'] || $hasMini['stats'] )
1746            echo PHP_EOL."<table align='center' class=tabla style='width:90%;' id='mini_log'>";
1747        if( $hasMini['logins'] ) {
1748            echo "<tr><td>".$this->miniLoginLog();
1749        }
1750        if( $hasMini['log'] ) {
1751            echo "<tr><td>".$this->miniLog();
1752        }
1753        if( $hasMini['stats'] ) {
1754            echo "<tr><td>".$this->miniStats();
1755        }
1756        if($hasMini['logins'] || $hasMini['log'] || $hasMini['stats'] )
1757            echo PHP_EOL."</table>";
1758    }
1759
1760    /**
1761     * iacase::forma_sequencial()
1762     *
1763     * @param string $h valor toca hacer normalmente param iah
1764     * @param string $nexth
1765     * @return
1766     */
1767    function forma_sequencial($h,$nexth='') {
1768        $ok=false;
1769        $this->msg_show();
1770        if($h!='a' && $this->log_cardex_view )
1771            $this->log('view',ia_htmlentities($this->label_record_summary()) );
1772        $hasMini=array('log'=>false,'logins'=>false,'stats'=>true);
1773        $isEdit=$h=='a' || $h=='i' || $h=='e' || $h=='s';
1774        $iCol=0;
1775        $divDataStyle = array_key_exists('moneda_id',$this->values) && $this->values['moneda_id']==2 ? "bold bg_green" : "bold bg_blue";
1776        $array_pages_bodega = ['bodega', 'producto_bodega', 'producto_general', 'color','estado_bodega', 'nota_bodega'];
1777        if (in_array($this->table, $array_pages_bodega))
1778            $divDataStyle = 'bold ';
1779        echo "<div id='divData' style='margin:auto;width:100%;' class='$divDataStyle'><table id='divDataTable' align='center' class=tabla style='width:96%;'>";
1780        if(!$this->forma_preFields($h,$nexth))
1781            return true;
1782        foreach($this->campos as $fieldName=>$f)
1783            if( !$this->primary_key_show && $fieldName==$this->pk_field )
1784                ;
1785            elseif(!$isEdit && $fieldName=='pwd')
1786                ;
1787            elseif( $f['modo']!='Hidden' && $f['modo']!='Nada' ) {
1788                if( $this->miniLogField($fieldName,$hasMini))
1789                    ;
1790                elseif( array_key_exists('formDisplayed',$this->campos[$fieldName]) )
1791                    ;
1792            else {
1793                    $lbl=$this->label_tag($fieldName);
1794                    $ok=true;
1795                    $tmpclass= !$isEdit || $f['modo']=='R/O' ? $this->data_div_read : $this->data_div_edit;
1796                    if( $iCol++ % $this->formTypeSecuencialCols==0 || (array_key_exists('br',$f) && $f['br'] ) ) {
1797                        echo PHP_EOL."<tr>";
1798                        $iCol=1;
1799                    }
1800                    echo "<td><div class='$tmpclass'>$lbl<br />".$this->show($fieldName).'</div>';
1801                    $this->campos[$fieldName]['formDisplayed']=true;
1802                }
1803            } elseif(  $f['modo']=='Hidden' )
1804                echo $this->show($fieldName);
1805        if(!$this->forma_postFields($h,$nexth))
1806            return true;
1807        echo PHP_EOL."</tbody></table>".PHP_EOL;
1808        if($this->forma_doChilds($h,$nexth)) {
1809            if($this->forma_doChilds($h,$nexth)) {
1810                if($this->editChilds && ($h=='e' || $h=='s' || ($this->table_info['pk_single_type']!='auto_increment' && ($h=='i' || $h=='a' )) ) ) {
1811                    $this->child_tables_show_all();
1812                } elseif($this->viewChilds && !($h=='a' || $h=='e' || $h=='s' || $h=='i' || $h=='')) {
1813                    $this->child_tables_show_all();
1814                }
1815            }
1816        }
1817        $ret=$this->forma_post($h,$nexth);
1818        $this->forma_miniLog($h,$hasMini);
1819        echo "</div>";
1820        $this->forma_postDiv($h,$nexth);
1821        return $ret;
1822    }
1823
1824function divDataTableStyle() { //VCA 29-05-2020
1825    if($this->table == 'cheque' || $this->table == 'pagare' || $this->table == 'vale')
1826    {
1827        foreach(array('paid'=>'', 'cancelado'=>'div_data_cancelado',  'atrasado'=>'div_data_atrasado', 'super_atrasado'=>'div_data_super_atrasado', 'pending'=>'div_data_pending', 'modificado'=>'div_data_modificado',) as $fieldName=>$color)
1828            if(!empty($this->values[$fieldName]))
1829                return "$color";
1830
1831//        if(!empty($this->values['delivered_directo']))
1832//            return "background:#33cccc;";
1833    }
1834//    return 'background:#ffffff;';
1835    return '';
1836}
1837    /**
1838     * iacase::forma_deduce()
1839     *
1840     * @param string $h valor toca hacer normalmente param iah
1841     * @param string $nexth
1842     * @return
1843     */
1844    function forma_deduce($h,$nexth='') {
1845        $ok=false;
1846        $this->msg_show();
1847        if($h!='a' && $this->log_cardex_view )
1848            $this->log('view',ia_htmlentities($this->label_record_summary()) );
1849        $hasMini=array('log'=>true,'logins'=>true,'stats'=>true);
1850        $isEdit = $h === 'a' || $h ==='i' || $h === 'e' || $h === 's';
1851        $divDataTableStyle = $this->divDataTableStyle();
1852
1853//        $divDataStyle = array_key_exists('moneda_id',$this->values) && $this->values['moneda_id']==2 ? "bold bg_green" : "bold bg_blue";
1854        $divDataStyle = ""; array_key_exists('moneda_id',$this->values) && $this->values['moneda_id']==2 ? "bold bg_green" : "bold bg_blue";
1855        $array_pages_bodega = ['bodega', 'producto_bodega', 'producto_general', 'color','estado_bodega', 'nota_bodega'];
1856        // dd_($this->table);
1857        if (in_array($this->table, $array_pages_bodega))
1858            $divDataStyle = 'bold ';
1859
1860        echo "<div id='divData' style='margin:auto;width:100%;' class='$divDataStyle'><table id='divDataTable' align='center' class='tabla $divDataTableStyle' style='width:96%;'>";
1861        if(!$this->forma_preFields($h,$nexth))
1862            return true;
1863        $fieldset=false;
1864        foreach($this->campos as $fieldName=>$f) { array_key_exists('modo',$f) ? :$f['modo']='R/O';
1865            $labelbr=array_key_exists('label_br',$f) ? $f['label_br'] : '<br />';
1866            if( array_key_exists('formfield_pre_function',$this->campos[$fieldName]) && !empty($this->campos[$fieldName]['formfield_pre_function']) ) {
1867                $this->{$this->campos[$fieldName]['formfield_pre_function']}($h,$nexth);
1868            }
1869            if( !$this->primary_key_show && $fieldName==$this->pk_field )
1870                ;
1871            elseif(!$isEdit && $fieldName=='pwd')
1872                ;
1873            elseif( $f['modo']!='Hidden' && $f['modo']!='Nada' ) {
1874                if( $this->miniLogField($fieldName,$hasMini))
1875                    ;
1876                elseif( array_key_exists('formDisplayed',$this->campos[$fieldName]) && $this->campos[$fieldName]['formDisplayed'] )
1877                    ;
1878                elseif( !empty($f['display_group']) ) {
1879                    $ok=true;
1880                    $grupo=$f['display_group'];
1881                    if($fieldset) {
1882                        echo PHP_EOL."</fieldset>";
1883                        $fieldset=false;
1884                    }
1885                    echo PHP_EOL."<tr><td>";
1886                    $labeld=false;
1887
1888                    foreach($this->campos as $agrupa=>$fAgrupa) {
1889                        $modoAgrupa = $fAgrupa['modo'] ?? 'R/O';
1890                        if ($modoAgrupa == 'Nada') continue;
1891
1892                        if(array_key_exists('display_group',$fAgrupa) && $fAgrupa['display_group']==$grupo) {
1893                            if( array_key_exists('display_group_break',$fAgrupa) && $fAgrupa['display_group_break'])
1894                                $break='clear:both;';
1895                            else
1896                                $break='float:left;';
1897                            if(!$labeld && array_key_exists('display_group_label',$fAgrupa) && !empty($fAgrupa['display_group_label']) ) {
1898                                if($fieldset)
1899                                    echo PHP_EOL."</fieldset>";
1900                                // echo PHP_EOL."<div class='$this->label_group'><b>".ia_htmlentities( $fAgrupa['display_group_label'])."</b></div>";
1901                                $display_group_fieldset_class = array_key_exists('display_group_fieldset_class',$fAgrupa) ? $fAgrupa['display_group_fieldset_class'] : "";
1902                                echo PHP_EOL."<fieldset id='$grupo' class='$this->label_group $display_group_fieldset_class'><legend>"
1903                                    .ia_htmlentities( $fAgrupa['display_group_label'])."</legend>";
1904                                $fieldset=true;
1905                            }
1906                            $labeld=true;
1907                            $tmpclass= !$isEdit || $f['modo']=='R/O' ? $this->data_div_read : $this->data_div_edit;
1908                            $class_remarks = '';
1909                            /*$fields_longText = ['remarks', 'remarks_internos', 'descripcion', 'remarks_paid'];
1910                            if (in_array($fieldName, $fields_longText)) {
1911                                $class_remarks = 'w-100';
1912                            } else {$class_remarks = '';}*/
1913                            echo PHP_EOL."<div id='div_$agrupa' class='$tmpclass $class_remarks' style='$break'>"
1914                                .$this->label_tag($agrupa,null,'','',array()).$labelbr.$this->show($agrupa)."</div>";
1915                            $this->campos[$agrupa]['formDisplayed']=true;
1916                            if( array_key_exists('form_field_postshow_function',$this->campos[$fieldName]) && !empty($this->campos[$fieldName]['form_field_postshow_function']) ) {
1917                                $this->{$this->campos[$fieldName]['form_field_postshow_function']}($h,$nexth);
1918                            }
1919                        }
1920                    }
1921                } else {
1922                    if($fieldset) {
1923                        echo PHP_EOL."</fieldset>";
1924                        $fieldset=false;
1925                    }
1926                   // echo "</form><form>";
1927                    $lbl= $f['modo']!='Hidden' ? $this->label_tag($fieldName) : "";
1928                    $ok=true;
1929                    $tmpclass= !$isEdit || $f['modo']=='R/O' ? $this->data_div_read : $this->data_div_edit;
1930                    $formato=$this->campo_key($fieldName,'formato');
1931                    echo PHP_EOL."<tr><td><div id='div_$fieldName' class='$tmpclass' style='" . ($formato=='fckeditor' ? "width:40%;":"") . "'>$lbl$labelbr".$this->show($fieldName).'</div>';
1932                    $this->campos[$fieldName]['formDisplayed']=true;
1933                            if( array_key_exists('form_field_postshow_function',$this->campos[$fieldName]) && !empty($this->campos[$fieldName]['form_field_postshow_function']) ) {
1934
1935                                $this->{$this->campos[$fieldName]['form_field_postshow_function']}($h,$nexth);
1936                            }
1937                }
1938            } elseif(  $f['modo']=='Hidden' ) {
1939                echo $this->show($fieldName);
1940                            if( array_key_exists('form_field_postshow_function',$this->campos[$fieldName]) && !empty($this->campos[$fieldName]['form_field_postshow_function']) ) {
1941
1942                                $this->{$this->campos[$fieldName]['form_field_postshow_function']}($h,$nexth);
1943                            }
1944            }
1945            if( array_key_exists('formfield_post_function',$this->campos[$fieldName]) && !empty($this->campos[$fieldName]['formfield_post_function']) ) {
1946                $this->{$this->campos[$fieldName]['formfield_post_function']}($h,$nexth);
1947            }
1948        }
1949        if($fieldset) {
1950            echo PHP_EOL."</fieldset>";
1951            $fieldset=false;
1952        }
1953
1954        if(!$this->forma_postFields($h,$nexth))
1955            return true;
1956        echo PHP_EOL."</tbody></table>".PHP_EOL;
1957        // childs!
1958        if($this->forma_doChilds($h,$nexth)) {
1959            if($this->editChilds && ($h=='e' || $h=='s' || (array_key_exists('pk_single_type', $this->table_info) && $this->table_info['pk_single_type']!='auto_increment' && ($h=='i' || $h=='a' )) ) ) {
1960                $this->child_tables_show_all();
1961            } elseif($this->viewChilds && !($h=='a' || $h=='e' || $h=='s' || $h=='i' || $h=='')) {
1962                $this->child_tables_show_all();
1963            }
1964        }
1965        $ret=$this->forma_post($h,$nexth);
1966        $this->forma_miniLog($h,$hasMini); //VCA ".$this->forma_miniLog($h,$hasMini)."
1967        echo "</div>";
1968        $this->forma_postDiv($h,$nexth);
1969
1970        return $ret;
1971    }
1972
1973    /**
1974     * iacase::forma_deduce4PDF()
1975     *
1976     * @param string $h valor toca hacer normalmente param iah
1977     * @param string $nexth
1978     * @return
1979     */
1980    function forma_deduce4PDF($h,$nexth='')
1981    {
1982        $ok=false;
1983        $divDataStyle = array_key_exists('moneda_id',$this->values) && $this->values['moneda_id']==2 ? "bold bg_green" : "bold bg_blue";
1984        //$divDataStyle = array_key_exists('moneda_id',$this->values) && $this->values['moneda_id']==2 ? "background-color:#02a702;" : '';
1985        $html4PDF = "<div id='divData' style='margin:auto;width:100%;' class='$divDataStyle'><table id='divDataTable' align='center' style='width:96%;'>";
1986        if(!$this->forma_preFields($h,$nexth))
1987            return '';
1988        $fieldset=false;
1989        foreach($this->campos as $fieldName=>$f) {
1990            $labelbr=array_key_exists('label_br',$f) ? $f['label_br'] : '<br />';
1991            if( array_key_exists('formfield_pre_function',$this->campos[$fieldName]) && !empty($this->campos[$fieldName]['formfield_pre_function']) ) {
1992                $this->{$this->campos[$fieldName]['formfield_pre_function']}($h,$nexth);
1993            }
1994            elseif( $f['modo']!='Hidden' && $f['modo']!='Nada' ) {
1995                if( array_key_exists('formDisplayed',$this->campos[$fieldName]) && $this->campos[$fieldName]['formDisplayed'] )
1996                    ;
1997                elseif( !empty($f['display_group']) ) {
1998                    $ok=true;
1999                    $grupo=$f['display_group'];
2000                    if($fieldset) {
2001                        $html4PDF.="</div>";
2002                        $fieldset=false;
2003                    }
2004                    $html4PDF.="<tr><td style='border:1px black solid; '>";
2005                    $labeld=false;
2006
2007                    foreach($this->campos as $agrupa=>$fAgrupa) {
2008                        if(array_key_exists('display_group',$fAgrupa) && $fAgrupa['display_group']==$grupo) {
2009                            if( array_key_exists('display_group_break',$fAgrupa) && $fAgrupa['display_group_break'])
2010                                $break='clear:both;';
2011                            else
2012                                $break='float:left;';
2013                            if(!$labeld && array_key_exists('display_group_label',$fAgrupa) && !empty($fAgrupa['display_group_label']) ) {
2014                                if($fieldset)
2015                                    $html4PDF.="</div>";
2016                                // echo PHP_EOL."<div class='$this->label_group'><b>".ia_htmlentities( $fAgrupa['display_group_label'])."</b></div>";
2017                                $html4PDF.="<div id='$grupo' class='$this->label_group'><legend>".ia_htmlentities( $fAgrupa['display_group_label'])."</legend>";
2018                                $fieldset=true;
2019                            }
2020                            $labeld=true;
2021                            $tmpclass= $this->data_div_read;
2022                            $html4PDF.="<div id='div_$agrupa' class='$tmpclass' style='$break'>"
2023                                .$this->label_tag($agrupa,null,'','',array()).$labelbr.$this->show($agrupa)."</div>";
2024                            $this->campos[$agrupa]['formDisplayed']=true;
2025                            if( array_key_exists('form_field_postshow_function',$this->campos[$fieldName]) && !empty($this->campos[$fieldName]['form_field_postshow_function']) ) {
2026                                $this->{$this->campos[$fieldName]['form_field_postshow_function']}($h,$nexth);
2027                            }
2028                        }
2029                    }
2030                } else {
2031                    if($fieldset) {
2032                        $html4PDF.="</div>";
2033                        $fieldset=false;
2034                    }
2035                   // echo "</form><form>";
2036                    $lbl=$this->label_tag($fieldName);
2037                    $ok=true;
2038                    $isEdit = $h === 'a' || $h === 'i' || $h === 'e' || $h === 's';
2039                    $tmpclass= !$isEdit || $f['modo']=='R/O' ? $this->data_div_read : $this->data_div_edit;
2040                    $html4PDF.="<tr><td style='border:1px black solid; '><div id='div_$fieldName' class='$tmpclass'>$lbl$labelbr".$this->show($fieldName).'</div>';
2041                    $this->campos[$fieldName]['formDisplayed']=true;
2042                            if( array_key_exists('form_field_postshow_function',$this->campos[$fieldName]) && !empty($this->campos[$fieldName]['form_field_postshow_function']) ) {
2043
2044                                $this->{$this->campos[$fieldName]['form_field_postshow_function']}($h,$nexth);
2045                            }
2046                }
2047            } elseif(  $f['modo']=='Hidden' ) {
2048                $html4PDF.=$this->show($fieldName);
2049                            if( array_key_exists('form_field_postshow_function',$this->campos[$fieldName]) && !empty($this->campos[$fieldName]['form_field_postshow_function']) ) {
2050
2051                                $this->{$this->campos[$fieldName]['form_field_postshow_function']}($h,$nexth);
2052                            }
2053            }
2054            if( array_key_exists('formfield_post_function',$this->campos[$fieldName]) && !empty($this->campos[$fieldName]['formfield_post_function']) ) {
2055                $this->{$this->campos[$fieldName]['formfield_post_function']}($h,$nexth);
2056            }
2057        }
2058        if($fieldset) {
2059            $html4PDF.="</div>";
2060            $fieldset=false;
2061        }
2062
2063        if(!$this->forma_postFields($h,$nexth))
2064            return true;
2065        $html4PDF.="</tbody></table>";
2066
2067
2068        $html4PDF.="</div>";
2069
2070
2071        return $html4PDF;
2072    }
2073
2074    function child_tables_show_all() {
2075    global $gAppRelate;
2076        $this->child_tables_default();
2077        if(empty($this->childTables))
2078            return;
2079        $iChild=0;
2080        $per=floor(100/$this->formTypeChildsPerRow);
2081        echo PHP_EOL."<table align='center' style='table-layout:fixed;width:96%;'>";
2082        foreach($this->childTables as $childDef)  if(!array_key_exists('hide',$childDef) || !$childDef['hide'] )  {
2083            $cols=$this->array_val('gridColspan', $gAppRelate->tables[$childDef['to_table']]['links_to'][$childDef['this_table']][$childDef['to_field']],1);
2084            if( $cols > 1) {
2085                $colspan="colspan='$cols'";
2086                $iChild+=$cols-1;
2087            } else
2088                $colspan='';
2089            if($iChild++ % $this->formTypeChildsPerRow==0 || $iChild>$this->formTypeChildsPerRow) {
2090                echo PHP_EOL."<tr>";
2091                if($iChild>$this->formTypeChildsPerRow)
2092                    $iChild=1;
2093            }
2094            echo PHP_EOL."<td class=izq $colspan style='width:$per%;'>";
2095            $this->child_table_jqgrid($childDef['childTableName'],'');
2096            echo "</td>";
2097        }
2098        echo PHP_EOL."</table>";
2099    }
2100
2101////////////////////////////////////
2102// FORM QBE
2103///////////////////////////////////
2104    /**
2105     * iacase::qbe_forma()
2106     *
2107     * @return @void
2108     */
2109    public function qbe_forma() {
2110         $conOri=$this->conOri;
2111         $this->conOri=false;
2112
2113         if($this->cols_search=='*')
2114            foreach($this->campos as $fieldName=>$f)
2115                $soloBusca[]=$fieldName;
2116         else
2117            $soloBusca=explode(',', str_replace(array("\r","\n","\t"," "),"",$this->cols_search) );
2118
2119         echo "<div id='divDataTable' style='margin:auto;width:100%;'><table id='divDataTable' align='center' class=tabla style='width:96%;'>";
2120         foreach($this->campos as $fieldName=>$f) {
2121            /*if(  array_key_exists('formato',$f) && $f['formato']=='fckeditor'  ) {
2122                $f['formato']='';
2123                $this->campos[$fieldName]['formato']='';
2124            }*/
2125            if( !in_array($fieldName,$soloBusca) )
2126                ;
2127            elseif( !$this->primary_key_show && $fieldName==$this->pk_field )
2128                ;
2129            elseif( $f['modo']!='Hidden' && $f['modo']!='Nada' && ( !array_key_exists('formato',$f) || $f['formato']!='attachment') ) {
2130                if( $this->miniLogField($fieldName,$hasMini))
2131                    ;
2132                elseif( array_key_exists('formDisplayed',$this->campos[$fieldName]) )
2133                    ;
2134                elseif( !empty($f['display_group']) ) {
2135                    $ok=true;
2136                    $grupo=$f['display_group'];
2137                    echo PHP_EOL."<tr><td>";
2138                    $labeld=false;
2139
2140                    foreach($this->campos as $agrupa=>$fAgrupa) if( in_array($agrupa,$soloBusca) ) {
2141                        if($fAgrupa['display_group']==$grupo) {
2142                            if( array_key_exists('display_group_break',$fAgrupa) && $fAgrupa['display_group_break'])
2143                                $break='clear:both;';
2144                            else
2145                                $break='float:left;';
2146                            if(!$labeld && array_key_exists('display_group_label',$fAgrupa) && !empty($fAgrupa['display_group_label']) ) {
2147                                echo PHP_EOL."<div class='$this->label_group'><b>".ia_htmlentities( $fAgrupa['display_group_label'])."</b></div>";
2148                            }
2149                            $labeld=true;
2150                            $tmpclass=  $this->data_div_edit;
2151                            $modo=null;
2152                            $formato=$this->campo_key($fieldName,'formato');
2153
2154                            echo PHP_EOL."<div id='div_$fieldName' class='$tmpclass' style='" . ($formato=='fckeditor' ? "width:40%;":"") . "$break'>"
2155                                .$this->label_tag($agrupa,null,'','',array())."<br/>".$this->input_auto($agrupa,array(),null,$modo,null,true)."</div>";
2156                            $this->campos[$agrupa]['formDisplayed']=true;
2157                        }
2158                    }
2159                } else {
2160                    $lbl=$this->label_tag($fieldName);
2161                    $ok=true;
2162                    $tmpclass= $this->data_div_edit;
2163                    $modo=null;
2164                    $sep='<br />';
2165                    $formato=$this->campo_key($fieldName,'formato');
2166
2167                    echo PHP_EOL."<tr><td><div class='$tmpclass' style='" . ($formato=='fckeditor' ? "width:98%;":"") . "'>$lbl$sep".$this->input_auto($fieldName,array(),null,$modo,null,true).'</div>';
2168                    $this->campos[$fieldName]['formDisplayed']=true;
2169                }
2170            }
2171         }
2172         echo "</div></table>";
2173         $this->conOri=$conOri;
2174    }
2175
2176
2177////////////////////////////////////
2178// MINI LOG: FORM RECORD LOG AND INFO FIELDS
2179///////////////////////////////////
2180    /**
2181     * iacase::miniLogField()
2182     *
2183     * @param string $fieldName nombre del campo
2184     * @param string $h valor toca hacer normalmente param iahasMini
2185     * @return
2186     */
2187    function miniLogField($fieldName,&$hasMini) {
2188        if($fieldName=='alta_db' || $fieldName=='alta_por' || $fieldName=='ultimo_cambio' || $fieldName=='ultimo_cambio_por' || $fieldName=='ultima_edicion'  || $fieldName=='ultima_edicion_por' ) {
2189            $hasMini['log']=true;
2190            return true;
2191        } elseif($fieldName=='logins' || $fieldName=='ultimo_login' || $fieldName=='ultimo_login_ip' ) {
2192            $hasMini['logins']=true;
2193            return true;
2194        } elseif($fieldName=='iac_edits' || $fieldName=='iac_last_edit_ip' || $fieldName=='iac_pageviews' || $fieldName=='iac_pageviews_last'  || $fieldName=='iac_pageviews_last_ip' ) {
2195            $hasMini['stats']=true;
2196            return true;
2197        }
2198        return false;
2199    }
2200
2201    /**
2202     * iacase::miniLog()
2203     *
2204     * @return
2205     */
2206    function miniLog() {
2207        $m='';
2208        $modo = "R/O";
2209        if(array_key_exists('iac_edits',$this->values) ) {
2210            $m.="<b>Cambios:</b> <i>".$this->show('iac_edits', modo: $modo)."</i>";
2211        }
2212        if( array_key_exists('ultimo_cambio',$this->values) || array_key_exists('ultimo_cambio_por',$this->values)
2213        ) {
2214            if($m!='')
2215                $m.='. ';
2216             $m.="<b>&Uacute;ltimo cambio</b>";
2217             if(array_key_exists('ultimo_cambio',$this->values) )
2218                $m.=" el: <i>".$this->show('ultimo_cambio', modo: $modo)."</i>";
2219             if(array_key_exists('ultimo_cambio_por',$this->values) )
2220                $m.=' por: <i>'.$this->show('ultimo_cambio_por', modo: $modo)."</i>";
2221            if(array_key_exists('iac_last_edit_ip',$this->values) )
2222                $m.=' IP: <i>'.$this->show('iac_last_edit_ip', modo: $modo)."</i>";
2223        }
2224        if(array_key_exists('alta_db',$this->values) || array_key_exists('alta_por',$this->values) ) {
2225            if($m!='')
2226                $m.='. | ';
2227            $m.=" <b>Alta</b>";
2228            if(array_key_exists('alta_db',$this->values) )
2229                $m.=" el: <i>".$this->show('alta_db', modo: $modo)."</i>";
2230            if(array_key_exists('alta_por',$this->values) )
2231                $m.=' por <i>'.$this->show('alta_por', modo: $modo)."</i>";
2232        }
2233        return $m;
2234    }
2235
2236    /**
2237     * iacase::miniStats()
2238     *
2239     * @return
2240     */
2241    function miniStats() {
2242        $m='';
2243        if(array_key_exists('iac_pageviews',$this->values) || array_key_exists('iac_pageviews_last',$this->values) ) {
2244            $m="<b>Consultas</b>";
2245            if(array_key_exists('iac_pageviews',$this->values) )
2246                $m.=": <i>".$this->show('iac_pageviews')."</i>";
2247            if(array_key_exists('iac_pageviews_last',$this->values) ) {
2248                $m.=" <b>&Uacute;ltima</b>";
2249                if(array_key_exists('iac_pageviews_last',$this->values) )
2250                    $m.=" el: <i>".$this->show('iac_pageviews_last').'</li>';
2251            }
2252        }
2253        return $m;
2254    }
2255
2256    /**
2257     * iacase::miniLoginLog()
2258     *
2259     * @return
2260     */
2261    function miniLoginLog() {
2262        $m='';
2263        if(array_key_exists('ultimo_login',$this->values) ) {
2264            $m.="&Uacute;ltimo login el ".$this->show('ultimo_login');
2265            if(array_key_exists('ultimo_login_ip',$this->values) )
2266                 $m.=" de ".$this->show('ultimo_login_ip');
2267        }
2268        if(array_key_exists('ultimo_login_ip',$this->values) ) {
2269            $m.="&Uacute;ltimo login de ".$this->show('ultimo_login_ip');
2270        }
2271
2272        if(array_key_exists('logins',$this->values) ) {
2273            if($m!='')
2274                $m.='. ';
2275            $m.="Total logins: ".$this->show('logins');
2276        }
2277        return $m;
2278    }
2279
2280////////////////////////////////////
2281// QBE LOGIC
2282///////////////////////////////////
2283    /**
2284     * iacase::qbe_where()
2285     *
2286     * @return
2287     */
2288    public function qbe_where() {
2289        $where='';
2290        $andor="AND"; // "OR" o " AND"
2291        $this->params_to_value(false,false,'',true);
2292        foreach($this->values as $fieldName=>$val) if(!empty($val)) {
2293            if(is_array($val))
2294                $val=implode(',',$val);
2295            else
2296                $val=trim($val);
2297            $c1=substr($val,0,1);
2298            $c2=substr($val,0,2);
2299
2300            $operset=false;
2301
2302            $oper='=';
2303            if(substr($fieldName,-3)=='_id')
2304                $operset=true;
2305            elseif($c2=='>=' || $c2=='=>') {
2306                $oper=">=";
2307                $val=substr($val,2);
2308                $operset=true;
2309            } elseif($c2=='<=' || $c2=='=>') {
2310                $oper="<=";
2311                $val=substr($val,2);
2312                $operset=true;
2313            } elseif($c2=='<>') {
2314                $oper="<>";
2315                $val=substr($val,2);
2316                $operset=true;
2317            } elseif($c1=='>' || $c1=='<' || $c1=='=') {
2318                $oper=$c1;
2319                $val=substr($val,1);
2320                $operset=true;
2321            }
2322
2323            $val=trim($val);
2324            $type=$this->campos[$fieldName]['Type'];
2325            $numeric=array_key_exists('numeric',$this->campos[$fieldName]) && $this->campos[$fieldName]['numeric'];
2326            if($type=='date' || $type=='datetime' || $type=='timestamp') {
2327                $where.=" $andor $fieldName $oper ".strit($val);
2328                $this->msg_aviso.="<li>".$this->label_field($fieldName)." $oper ".ia_htmlentities($val);
2329            }elseif($numeric) {
2330                $where.=" $andor $fieldName $oper ".strit($val);
2331                $this->msg_aviso.="<li>".$this->label_field($fieldName)." $oper ".ia_htmlentities($val);
2332            }elseif($type=='bit') {
2333                $where.=" $andor $fieldName $oper ".strit($val);
2334                $this->msg_aviso.="<li>".$this->label_field($fieldName)." $oper ".ia_htmlentities($val);
2335            }elseif($operset) {
2336                $where.=" $andor $fieldName $oper ".strit($val);
2337                $this->msg_aviso.="<li>".$this->label_field($fieldName)." $oper ".ia_htmlentities($val);
2338            }else {
2339                $where.=" $andor $fieldName like ".strit("%$val%");
2340                $this->msg_aviso.="<li>".$this->label_field($fieldName)." contiene ".ia_htmlentities($val);
2341           }
2342        }
2343        $como = $andor=='AND' ? 'todos' : 'cualsea';
2344        if(!empty($where))
2345            $this->msg_aviso="<li>Criterios (cumplan $como)<ul>$this->msg_aviso</ul>";
2346        else
2347            $this->msg_aviso="<li>Criterios<ul>Buscar todos</ul>";
2348        return substr( trim($where),strlen($andor) );
2349    }
2350
2351    /**
2352     * iacase::qbe_resultados()
2353     *
2354     * @return
2355     */
2356    public function qbe_resultados() {
2357        $where = $this->qbe_where();
2358        $this->extraParams['qbeWhere']=$where;
2359        $this->extraParams['qbeEn']=1;
2360        $this->listme('qbr'.$this->table,'Resultado de la busqueda de '.$this->label_list() ,$where);
2361    }
2362
2363
2364    /**
2365     * iacase::listme_pre()
2366     *
2367     * @param mixed $grid
2368     * @return
2369     */
2370    function listme_pre($grid) { return true; }
2371    /**
2372     * iacase::listme_preRender()
2373     *
2374     * @param mixed $grid
2375     * @return
2376     */
2377    function listme_preRender($grid) { return true; }
2378    /**
2379     * iacase::listme_post()
2380     *
2381     * @param mixed $grid
2382     * @return void
2383     */
2384    function listme_postRender($grid) {  }
2385
2386    /**
2387     * iacase::listme()
2388     *
2389     * @param string $noUsar
2390     * @param string $title
2391     * @param string $where
2392     * @return
2393     */
2394    function listme($noUsar='',$title='',$where='',$jsAfter='',$postData=array() ) { //,$sendOnly=array()
2395         //if(empty($sendOnly))
2396            $sendOnly=$this->jqGridSendOnly;
2397
2398        $this->iajqgrid_actions($this->iajqgrid_actions_extra);
2399        // id del grid y nombre del gridVar
2400        //if(empty($gridId))
2401            $gridId=$this->jqGridId;
2402        $this->jqGridId=$gridId;
2403        $this->jgGridVar=$this->jqGridId.'_var';
2404
2405        if($where=='')
2406            $where=$this->list_where;
2407        //echo "<li>" . $where;
2408        //echo "<li>" . $this->list_where;
2409        if(property_exists($this,'doGridCaption'))
2410        {
2411            if(empty($title))
2412                $title=$this->label_list();
2413        }
2414        else
2415            $title = '';
2416        $this->msg_show();
2417
2418        $soloJqGrid=$this->modo=='jqgrid_form'  || $this->modo=='jqgrid_inline' ;
2419        $puedeEditar=$this->may_add() || $this->may_edit() || $this->may_delete();
2420
2421        $grid=new iaJQGrid_base($gridId,$title,$this->jqGridEditable && ( ($soloJqGrid && $puedeEditar) || ($this->modo=='jqgrid_iacform' && $this->may_delete())),$this->jqGridSaveState);
2422        if(!$this->listme_pre($grid))
2423            return;
2424
2425        $grid->set_option('autowidth',"false");
2426        $grid->set_option('height',"400");
2427        $grid->set_option('hidegrid',false);
2428        $grid->set_option('mtype','POST');
2429        if(!$this->asChild) {
2430            $grid->set_option('width',"screen.width-90");
2431            $grid->set_option('width',"\$($grid->gridVar).parent().width()-25");
2432            if(!empty( $this->jqGrid_options)) foreach($this->jqGrid_options as $k=>$v)
2433                $grid->set_option($k,$v);
2434        } else {
2435            $grid->set_option('width',"\$($grid->gridVar).parent().width()-25");
2436            if(!empty($this->child_jqGrid_option)) foreach($this->child_jqGrid_option as $k=>$v)
2437                $grid->set_option($k,$v);
2438        }
2439        $grid->rownumbers();
2440        $grid->set_option('sortname',$this->list_sortname_dflt);
2441        $grid->set_option('sortorder',$this->list_sortorder_dflt);
2442        //$grid->multiselect(true,20,false,'shiftKey');
2443        if($this->_grid_ondblClickRow)
2444            $grid->click_grow_row();
2445
2446/*
2447        $actions=array();
2448        if(true || $this->modo=='cardex_window') {
2449                $actions=array( 'externEdit'=>$this->may_edit()
2450                    ,'externView'=>$this->may_read()
2451                    ,'extern'=>array(
2452                        'edit'=>  $this->may_edit() ? array('icon'=>'ui-icon-pencil','title'=>'Editar','url'=>$_SERVER['SCRIPT_NAME'],'target'=>'_blank','params'=>'&iah=e') : false
2453                        ,'view'=> $this->may_read() ? array('icon'=>'ui-icon-document','title'=>'Consultar','url'=>$_SERVER['SCRIPT_NAME'],'target'=>'_blank','params'=>'&iah=r')  : false
2454                        )
2455                    ,'formatoptions'=> array('editbutton'=>false,'editformbutton'=>false,'delbutton'=>false)
2456                );
2457        } elseif($this->modo=='jqgrid_iacform') {
2458            if($this->may_edit()|| $this->may_read()) {
2459                $actions=array( 'externEdit'=>$this->may_edit()
2460                    ,'externView'=>$this->may_read()
2461                    ,'extern'=>array(
2462                        'edit'=>  $this->may_edit() ? array('dialog'=>true) : null
2463                        ,'view'=> $this->may_read() ? array('dialog'=>true)  : false
2464                        )
2465                    ,'formatoptions'=> array('editbutton'=>false,'editformbutton'=>false,'delbutton'=>false)
2466                );
2467             }
2468        } elseif($soloJqGrid) {
2469            $actions=array( 'externEdit'=>false,'externView'=>false
2470                ,'formatoptions'=> array(
2471                    'editbutton'=>$this->may_edit() && $this->modo=='jqgrid_inline',
2472                    'editformbutton'=>$this->may_edit() && $this->modo=='jqgrid_form',
2473                    'delbutton'=>$this->may_delete())
2474            );
2475        } elseif($this->may_edit() || $this->may_read()) {
2476            $actions=array( 'externEdit'=>$this->may_edit()
2477                ,'externView'=>$this->may_read()
2478                ,'formatoptions'=> array('editbutton'=>false,'editformbutton'=>false,'delbutton'=>false)
2479
2480            );
2481        }
2482*/
2483        $extraParams=array();
2484        if(!empty($this->extraParams)) foreach($this->extraParams as $k=>$d)
2485            $extraParams[$k]=$d;
2486        if($this->cols_list=='*' || empty($this->cols_list) )
2487            $showOnly=array();
2488        else {
2489            $showOnly=explode(',',$this->cols_list);
2490        }
2491
2492
2493        $grid->colModel_iacase($this,$this->jqGridActions,$this->col_list_noShow,$this->jqGridHiddenCols,$showOnly,$this->colModel_overRide,array()
2494            ,$where,true,!$this->primary_key_show,$extraParams,$sendOnly);
2495       // if($soloJqGrid) // 2 veces pa llenar editData y delData
2496       //     $grid->colModel_iacase($this,$this->jqGridActions,array(),array(),array(),array(),array(),'',true,!$this->primary_key_show,$extraParams);
2497
2498        if(!empty($postData)) foreach($postData as $k=>$v)
2499            $grid->postData[$k]=$v;
2500        $grid->pager();
2501        $grid->navigator($this, array( 'add'=>$this->may_add() && $soloJqGrid,'edit'=>false
2502            ,'del'=> ($soloJqGrid || $this->modo=='jqgrid_iacform') && $this->may_delete()
2503            ,'view'=>false
2504            ,'search'=>$this->jqGridSearch )
2505            ,null,array(),array(),array(),array() ); // despues de poner postData ie en colModel_iacase
2506        $grid->column_chooser();
2507        if($this->jqGridFilters) {
2508            $grid->toolbar_filter(true,true,$this->jqGridFiltersVisible);
2509        }
2510
2511        //$grid->exporta();
2512
2513//        $grid->resize_grid();
2514        // remove close button $('.ui-jqgrid-titlebar-close','#gview_mysimpletable').remove();
2515
2516        if(!empty($jsAfter))
2517            $grid->javascriptAfter($jsAfter,'jsAfter');
2518
2519        if(!$this->listme_preRender($grid))
2520            return;
2521        echo "<div style='margin:auto;width:100%;'>";
2522        $grid->render();
2523
2524        $this->listme_postRender($grid);
2525        $busqueda_rapida_automatica = $this->busqueda_rapida_automatica ? 'true':'false';
2526        $sin_busqueda_rapida = empty($this->sin_busqueda_rapida) ? 'false' : 'true';
2527        echo "</div>";
2528        echo <<<FACTIONS
2529            <script>
2530                newItem = iacaseNewItem;
2531                \$vitex_globales = \$vitex_globales || {};
2532                \$vitex_globales["busqueda_rapida_automatica"] = $busqueda_rapida_automatica
2533                \$vitex_globales["sin_busqueda_rapida"] = $sin_busqueda_rapida
2534                selected_row_id = typeof selected_row_id !== "undefined" ? selected_row_id : "";
2535                last_edited_row_id = '';
2536            </script>
2537FACTIONS;
2538        ob_flush();
2539        flush();
2540    }
2541
2542    function iajqgrid_actions($botonArray=array()) {
2543      //$this->jqGridActions=array(); //la llena en automnatico $this->
2544//$botonArray[0]=array('icon'=>'ui-icon-document','title'=>'test','url'=>'coso.php','target'=>'_self','params'=>'','id'=>'iaid');
2545//$botones[]=array( // TODOS obligartorios menos dicen OPCIONAL
2546//,'url'=>'js function/url','title'=>'glolbito'
2547//,'isjs'=>true es javascript, false o no definido es url OPCIONAL
2548//,'dialog' en true y js manda solol id del row, en false id, rowindex OPCIONAL
2549//,'icon'=>'nombre icono jqgrid'
2550//,'id'=>iaid el para el id del url
2551//,'target'=>'_blank','params'=>'&x=2&t=..') ;
2552        //if(!empty($this->jqGridActions))
2553        //    return;
2554//FALTA actions predfined in $this->jqGridActions
2555//FALTA delete en actions col
2556        if(!$this->may_read() && !$this->may_update() && empty($botonArray)) {
2557            return array();
2558        }
2559        $soloJqGrid=$this->modo=='jqgrid_form'  || $this->modo=='jqgrid_inline' ;
2560        if($this->modo=='cardex_window') {
2561            //VCA Para poder quitar la columna de actions.
2562            if(property_exists($this, "no_actions") && $this->no_actions === true)
2563                $this->jqGridActions=array();
2564            else{
2565                $this->jqGridActions=array( 'externEdit'=>$this->may_edit()
2566                    ,'externView'=>$this->may_read()
2567                    ,'extern'=>array(
2568                        'edit'=>  $this->may_edit() ? array('icon'=>'fa-icon fa-duotone fa-pen-to-square txt_shadow_blue tooltip_toolbar_wohtml txt_1_3em','title'=>'Editar','url'=>$_SERVER['SCRIPT_NAME'],'target'=>'_blank','params'=>'&iah=e', 'rel'=>'opener refferer', 'fontawesome' => 'fa-icon') : false
2569                        ,'view'=> $this->may_read() ? array('icon'=>'ui-icon-document','title'=>'Consultar','url'=>$_SERVER['SCRIPT_NAME'],'target'=>'_blank','params'=>'&iah=r', 'rel'=>'opener refferer')  : false
2570                        )
2571                    ,'formatoptions'=> array('editbutton'=>false,'editformbutton'=>false,'delbutton'=>false)
2572                );
2573            }
2574        } elseif($this->modo=='jqgrid_iacform') {
2575            if($this->may_edit()|| $this->may_read()) {
2576                $this->jqGridActions=array( 'externEdit'=>$this->may_edit()
2577                    ,'externView'=>$this->may_read()
2578                    ,'extern'=>array(
2579                        'edit'=>  $this->may_edit() ? array('dialog'=>true) : null
2580                        ,'view'=> $this->may_read() ? array('dialog'=>true)  : false
2581                        )
2582                    ,'formatoptions'=> array('editbutton'=>false,'editformbutton'=>false,'delbutton'=>false)
2583                );
2584             }
2585        } elseif($soloJqGrid) {
2586            $this->jqGridActions=array( 'externEdit'=>false,'externView'=>false
2587                ,'formatoptions'=> array(
2588                    'editbutton'=>$this->may_edit() && $this->modo=='jqgrid_inline',
2589                    'editformbutton'=>$this->may_edit() && $this->modo=='jqgrid_form',
2590                    'delbutton'=>$this->may_delete())
2591            );
2592        } elseif($this->may_edit() || $this->may_read()) {
2593            $this->jqGridActions=array( 'externEdit'=>$this->may_edit()
2594                ,'externView'=>$this->may_read()
2595                ,'extern'=>array(
2596                    'edit'=>  $this->may_edit() ? array('icon'=>'ui-icon-pencil','title'=>'Editar','url'=>$_SERVER['SCRIPT_NAME'],'target'=>'_self','params'=>'&iah=e', 'rel'=>'opener refferer') : false
2597                    ,'view'=> $this->may_read() ? array('icon'=>'ui-icon-document','title'=>'Consultar','url'=>$_SERVER['SCRIPT_NAME'],'target'=>'_self','params'=>'&iah=r', 'rel'=>'opener refferer')  : false
2598                    )
2599                ,'formatoptions'=> array('editbutton'=>false,'editformbutton'=>false,'delbutton'=>false)
2600
2601            );
2602        }
2603        if(!empty($botonArray)) foreach($botonArray as $b) {
2604             $this->jqGridActions['extern'][]=$b;
2605        }
2606        // dd_($botonArray, $this->jqGridActions['extern']);
2607    }
2608
2609    function child_jqgrid_actions($pagina,$class, $doAction,$view,$edit,$insert,$delete,$botonArray=array()) {
2610      //$this->jqChildGridActions=array(); //la llena en automnatico $this->
2611//$botonArray[0]=array('icon'=>'ui-icon-document','title'=>'test','url'=>'coso.php','target'=>'_self','params'=>'','id'=>'iaid');
2612//$botones[]=array( // TODOS obligartorios menos dicen OPCIONAL
2613//,'url'=>'js function/url','title'=>'glolbito'
2614//,'isjs'=>true es javascript, false o no definido es url OPCIONAL
2615//,'dialog' en true y js manda solol id del row, en false id, rowindex OPCIONAL
2616//,'icon'=>'nombre icono jqgrid'
2617//,'id'=>iaid el para el id del url
2618//,'target'=>'_blank','params'=>'&x=2&t=..') ;
2619
2620// falta delete en actions col
2621    if(empty($this->jqChildGridActions)) {
2622
2623            $soloJqGrid=$class->modo=='jqgrid_form'  || $class->modo=='jqgrid_inline' ;
2624            if($class->modo=='cardex_window') {
2625
2626                    $this->jqChildGridActions=array( 'externEdit'=>$edit
2627                        ,'externView'=>$view
2628                        ,'extern'=>array(
2629                            'edit'=>  $edit ? array('icon'=>'ui-icon-pencil','title'=>'Editar','url'=>$pagina,'target'=>'_blank','params'=>'&iah=e') : false
2630                            ,'view'=> $view ? array('icon'=>'ui-icon-document','title'=>'Consultar','url'=>$pagina,'target'=>'_blank','params'=>'&iah=r')  : false
2631                            )
2632                        ,'formatoptions'=> array('editbutton'=>false,'editformbutton'=>false,'delbutton'=>false)
2633                    );
2634
2635            } elseif($class->modo=='jqgrid_iacform') {
2636
2637                if($edit|| $view) {
2638                    $this->jqChildGridActions=array( 'externEdit'=>$edit
2639                        ,'externView'=>$view
2640                        ,'extern'=>array(
2641                            'edit'=>  $edit ? array('dialog'=>true) : null
2642                            ,'view'=> $view ? array('dialog'=>true)  : false
2643                            )
2644                        ,'formatoptions'=> array('editbutton'=>false,'editformbutton'=>false,'delbutton'=>false)
2645                    );
2646                 }
2647
2648            } elseif($soloJqGrid) {
2649
2650                $this->jqChildGridActions=array( 'externEdit'=>false,'externView'=>false
2651                    ,'formatoptions'=> array(
2652                        'editbutton'=>$edit && $this->modo=='jqgrid_inline',
2653                        'editformbutton'=>$edit && $this->modo=='jqgrid_form',
2654                        'delbutton'=>$delete
2655                    )
2656               );
2657
2658            } elseif($edit || $view) {
2659
2660                $this->jqChildGridActions=array( 'externEdit'=>$edit
2661                    ,'externView'=>$view
2662                    ,'formatoptions'=> array('editbutton'=>false,'editformbutton'=>false,'delbutton'=>false)
2663
2664                );
2665            }
2666        }
2667        if(property_exists($this, "child_actions_as_parent") && $this->child_actions_as_parent == true)
2668            $botonArray = $this->iajqgrid_actions_extra;
2669
2670        if(!empty($botonArray)) foreach($botonArray as $b) {
2671             $this->jqChildGridActions['extern'][]=$b;
2672        }
2673
2674        return $this->jqChildGridActions;
2675    }
2676////////////////////////////////////
2677// TOOLBAR
2678///////////////////////////////////
2679    /**
2680     * iacase::toolbar_set()
2681     *
2682     * @param string $h valor toca hacer normalmente param iah
2683     * @param mixed $imgPath
2684     * @param mixed $extraParams
2685     * @return
2686     */
2687    function toolbar_set($h=null,$imgPath=null,$extraParams=array() ) {
2688        $dobleAdd = '';
2689        //$id=$this->id;
2690        if($h==null)
2691            $h=$this->h;
2692
2693        if($imgPath==null)
2694            $imgPath='/img';
2695
2696        $params='';
2697        if(!empty($extraParams)) foreach($extraParams as $k=>$p)
2698            $params.="&$k=".urlencode($p);
2699        if(!empty($this->extraParams)) foreach($this->extraParams as $k=>$p)
2700            $params.="&$k=".urlencode($p);
2701        $cardex_grid=param('iagridvar');
2702        if(!empty($cardex_grid))
2703            $params.="&iagridvar=$cardex_grid";
2704        if( $this->modo=='cardex_window' && !empty($cardex_grid) && !empty($h) && $this->h!='sinpermiso' && $h!='sinpermiso'  ) {
2705            $this->dialog_soy=true;
2706        }
2707
2708
2709        //falta dfltparams
2710        $this->paramsAmp = $paramAmp=$params;
2711        $params=substr($params,1);
2712
2713        //$save="<figure id='iaGuardar'><input class=inputimage title='Guardar este ".ia_htmlentities($this->label)." y verlo' alt='Guarda' src='$imgPath/guardar.png' type=image  name='iag'/><img style='display:none' id=iaGuardarCambio src='$imgPath/guarda_cambio.gif' title='Guarda los cambios y muestra el ".ia_htmlentities($this->label)."'/><figcaption>Guardar <strong>(F2)</strong></figcaption></figure>";
2714        $save="<figure id='iaGuardar' style='display:none'><input class='inputimage blink tooltip_toolbar_wohtml' title='Guardar este ".ia_htmlentities($this->label)." y verlo' alt='Guarda' src='../$imgPath/icons/Save.png' type=image  name='iag'/><img style='display:none' id=iaGuardarCambio src='../$imgPath/icons/Save.png' title='Guarda los cambios y muestra el ".ia_htmlentities($this->label)."'/><figcaption>Guardar <strong>(F2)</strong></figcaption></figure>";
2715        $saveNew="<figure><input class=inputimage src='$imgPath/save_and_new.png' type=image id='iaGuardarNew' name='iagNew' alt='Guarda y crea otro' title='Guardar los cambios e inmediatamente crear un nuevo ".ia_htmlentities($this->label)."'/><figcaption>Guarda y Alta</figcaption></figure>";
2716        $logParam='';
2717        if(param('table')!='')
2718            $logParam.='&table='.param('table');
2719        if(param('iacrecord')!='')
2720            $logParam.='&iacrecord='.param('iacrecord');
2721
2722
2723        $target=$this->modo=='cardex_window' ? ' target="_blank"' : '';
2724        if(empty($cardex_grid) && $this->modo=='cardex_window' )
2725            $paramAdd="&iagridvar=".$this->jqGridId."_var";
2726        else
2727            $paramAdd='';
2728        //VCA Cheque DD
2729        //Doc2pdf
2730        $doc2pdf_tabla = $this->table;
2731        if($this instanceof app_cheque) {
2732            $paramAdd .= "&CDD=NO";
2733            //$doc2pdf_tabla = "cheque_dd";
2734        }
2735        elseif(property_exists($this, "CDD") || $this instanceof app_cheque_dd) {
2736            $paramAdd .= "&CDD=$this->CDD";
2737            $doc2pdf_tabla = "cheque_dd";
2738        }
2739        if(!$this->dialog_soy) { // toolbar normal
2740            $this->jsvars .= "<script>var iac_modo=\"$this->modo\",iac_id=\"$this->id\",iac_form_id=\"$this->formId\";</script>";
2741            $this->toolbar=array(
2742
2743                'useris'=>''
2744                ,'title'=>''
2745                ,'home'=>array('html'=>"<div id='iaHomeNew' style='position: relative;'><a href='../backoffice/index.php' id='iaHome' class='tooltip_toolbar' title='<div class=\"bold ui_tooltip_grid_notas_modificacion_importante_si\" >Abrir Vitex en otra pestaña</div>' target='_blank'><img src='../$imgPath/icons/Home.png' alt='Home'/></a><br/><a href='../backoffice/index.php' class='tooltip_toolbar toolbar_cheques' title='<div class=\"ui_tooltip_grid_notas_verificacion_completa\">Inicio</div>'><strong>Inicio</strong></a></div>")
2746
2747                ,'save'=>array('condition'=>"return ((\$h=='e' || \$h=='a') && !empty(\$id) && \$this->may_update() );"
2748                    ,'html'=>$save)
2749
2750                ,'save'=>array('condition'=>"return (\$h=='e' && !empty(\$id) && \$this->may_update() ) || (\$h=='a' && \$this->may_add() );"
2751                    ,'html'=>$save)
2752
2753                ,'save_new'=>array('condition'=>"return ( (\$h=='e' && !empty(\$id) && \$this->may_update() ) || \$h=='a' ) && \$this->may_add() ;"
2754                    ,'html'=>$saveNew)
2755
2756                //qbe set
2757                    // save and next prev?
2758                    // pager
2759
2760                ,'list'=>array('condition'=>"return \$this->may_list();"
2761                    ,'html'=>"<a href='$_SERVER[PHP_SELF]?$params$logParam' title='Listado de ".$this->label_table_plural()."'><img src='$imgPath/listado.png' alt='Listado' title='Listado completo de ".$this->label_table_plural()."' /><br />Listar</a>")
2762
2763                ,'search'=>array('condition'=>"return \$this->may_list() && \$h!='qbe';"
2764                    ,'html'=>"<a href='$_SERVER[PHP_SELF]?iah=qbe$paramAmp$logParam' title='B&uacute;squeda de ".$this->label_table_plural()."'><img alt='Buscar' src='$imgPath/busqueda_avanzada.png' title='Nueva busqueda de ".$this->label_table_plural()."'/><br />Buscar</a>")
2765
2766                ,'find'=>array('condition'=>"return \$h=='qbe';"
2767                    ,'html'=>"<input type=submit name=qbr value='Buscar' />"
2768                    )
2769                //qbe navigation
2770
2771                ,'add'=>array('condition'=>"return (\$h!='a' || \$h=='e' || \$h=='b') && \$this->may_add()  && !(\$this->modo=='jqgrid_form'  || \$this->modo=='jqgrid_inline');"
2772                    ,'html'=>"<a rel='opener refferer' href='$_SERVER[PHP_SELF]?iah=a$paramAmp$paramAdd'$target id='iaNewItem' title='Alta o crear un nuevo ".$this->label."' class='toolbar_generico'><img src='../img/icons/New.png' alt='Alta' title='Crear un nuevo registro' /><br />Alta <strong>(F3)</strong></a>")
2773
2774                ,'edit'=>array('condition'=>"return (\$h=='r' || \$h=='b') && !empty(\$id) && \$this->may_edit();"
2775                    ,'html'=>"<a href='$_SERVER[PHP_SELF]?iah=e&iaid=$this->id$paramAmp' title='Editar'><img src='$imgPath/editar.png' alt='Editar' title='Cambiar el registro' /><br />Editar</a>")
2776                ,'read'=>array('condition'=>"return (\$h=='e' || \$h=='b') && !empty(\$id) && \$this->may_read();"
2777                    ,'html'=>"<a href='$_SERVER[PHP_SELF]?iah=r&iaid=$this->id$paramAmp' title='Ver'><img src='$imgPath/ver.png' alt='Consultar' title='Ver' /><br />Consultar</a>")
2778                ,'delete_ask'=>array('condition'=>"return (\$h=='r') && !empty(\$id) && \$this->may_delete();"
2779                    ,'html'=>"<a href='$_SERVER[PHP_SELF]?iah=b&iaid=$this->id$paramAmp' title='Solicitar Borrar este registro'><img src='$imgPath/borrar.png' alt='Borrar' title='Solicitar Borrar este registro' /><br />Borrar</a>")
2780                ,'delete'=>array('condition'=>"return (\$h=='b') && !empty(\$id) && \$this->may_delete();"
2781                    ,'html'=>"<a href='$_SERVER[PHP_SELF]?iah=d&iaid=$this->id$paramAmp' title='Confirmar Borrar'><img src='$imgPath/borrar_ok.png' alt='Confirme Borrar' title='Confirmar Borrar'/><br />Confirme borrar</a>")
2782
2783                //copy
2784                ,'export_cardex'=>array('condition'=>"return (\$h=='r' || \$h=='b' ) && !empty(\$id)  && \$this->may_export();"
2785                    ,'html'=>"<a href='$_SERVER[PHP_SELF]?iah=export&iaid=$this->id$paramAmp' title='Exportar'><img src='$imgPath/export.png' alt='Exportar' title='Exportar' />Exportar</a>")
2786                ,'print'=>array('condition'=>"return false && (\$h=='r' || \$h=='b' ) && !empty(\$id)  && \$this->may_print();"
2787
2788                    ,'html'=>"<a href='$_SERVER[PHP_SELF]?iah=print$paramAmp' title='Imprimir'><img src='../$imgPath/icons/printer.png' alt='Imprimir' title='Imprimir' /></a>")
2789
2790                ,'pdf'=>array('condition'=>"return (\$h=='r' || \$h=='b' || \$h=='e' || \$h=='s') && !empty(\$id) && (\$this->table == 'compra' || \$this->table == 'iac_usr' || \$this->table == 'iac_parametros' || \$this->table == 'movimientos' || \$this->table == 'nota_bodega');"
2791                    ,'html'=>"<a href='#' onclick='opcionesDePDF(\"$doc2pdf_tabla\", \"$this->id\");' id='iaDoc2PDF' title='Generar PDF'><img src='$imgPath/pdf_file.png' alt='Generar PDF' title='Generar PDF' /><br /><strong>PDF</strong></a>")
2792                
2793             ,'img'=>array('condition'=>"return (\$h=='r' || \$h=='b' || \$h=='e' || \$h=='s') && !empty(\$id) && (\$this->table == 'compra' || \$this->table == 'iac_usr' || \$this->table == 'iac_parametros' || \$this->table == 'movimientos' || \$this->table == 'nota_bodega');"
2794                    ,'html'=>"<a href='#' onclick='opcionesDePDF(\"$doc2pdf_tabla\", \"$this->id\",\"\",\"JPG\");' id='iaDoc2PDF' title='Generar JPG'><img src='../img/icons/Pictures.png' alt='Generar JPG' title='Generar JPG' /><br /><strong>JPG</strong></a>")
2795
2796
2797             ,'new_pdf'=>array('condition'=>"return (\$h=='r' || \$h=='b' || \$h=='e' || \$h=='s') && !empty(\$id) && (\$this->table == 'cheque' || \$this->table == 'vale' || \$this->table == 'pagare');"
2798                    ,'html'=>"<a href='#' onclick='exporter.pdf_table();' id='iaDoc2PDF' title='Generar PDF'><img src='$imgPath/pdf_file.png' alt='Generar PDF' title='Generar PDF' /><br /><strong>PDF</strong></a>")
2799
2800             ,'new_img'=>array('condition'=>"return (\$h=='r' || \$h=='b' || \$h=='e' || \$h=='s') && !empty(\$id) && (\$this->table == 'cheque' || \$this->table == 'vale' || \$this->table == 'pagare');"
2801                    ,'html'=>"<a href='#' onclick='exporter.imageSave();' id='iaDoc2PDF' title='Generar JPG'><img src='../img/icons/Pictures.png' alt='Generar JPG' title='Generar JPG' /><br /><strong>JPG</strong></a>")
2802
2803            ,'new_copy_image'=>array('condition'=>"return (\$h=='r' || \$h=='b' || \$h=='e' || \$h=='s') && !empty(\$id) && (\$this->table == 'cheque' || \$this->table == 'vale' || \$this->table == 'pagare');"
2804                ,'html'=>"<a href='#' onclick='exporter.imageCopy();' id='iaCopyJPG' title='Copiar JPG'><img src='../img/icons/Paste.png' alt='Copiar JPG' title='Copiar JPG' /><br /><strong>Copy JPG</strong></a>")
2805
2806                /* \$this->table == 'cheque' || \$this->table == 'compra' || \$this->table == 'pagare' || \$this->table == 'vale' || \$this->table == 'iac_usr' || \$this->table == 'iac_parametros' || \$this->table == 'movimientos' || \$this->table == 'nota_bodega'
2807                <a href='javascript:void(0);' onclick='print_nota();' title='Print' target='_self'><img src='../img/icons/printer.png' alt='Print' title='Print' /><br/><strong>Print</strong></a>
2808                */
2809//            ,'new_print'=>array('condition'=>"return (\$h=='r' || \$h=='b' || \$h=='e' || \$h=='s') && !empty(\$id) && (\$this->table == 'vale');"
2810//                    ,'html'=>"<a href='#' onclick='ia_imprime_doc();' id='ianew_print' title=''><img src='../img/icons/printer.png' alt='Print' title='Print' /><br /><strong>Print</strong></a>")
2811
2812                ,'pdfMasivo'=>array('condition'=>"return ((\$this->table == 'iac_usr' || \$this->table == 'iac_parametros') && empty(\$id));"
2813                    ,'html'=>"<a href='#' onclick='opcionesDePDF(\"$this->table\", \"$this->id\");' id='iaDoc2PDF' title='Generar PDF Masivo'><img src='$imgPath/pdf_file.png' alt='Generar PDF Masivo' title='Generar PDF Masivo' /><br /><strong>PDF<br/>Masivo</strong></a>")
2814
2815                ,'log'=>array('condition'=>"return (\$h=='r' || \$h=='b' || \$h=='e') && !empty(\$id) && \$this->may_viewLog();"
2816                    ,'html'=>"<a href='bitacora.php?table=$this->table&record=$this->id' title='Bit&aacute;cora' target='_blank'><img src='$imgPath/bitacora.png' alt='Log' title='Bit&aacute;cora del registro' /><br />Bit&aacute;cora</a>")
2817                ,'log_all'=>array('condition'=>"return (\$h=='' || \$h=='l' || \$h=='qbr') && \$this->may_viewLog();"
2818                    ,'html'=>"<a href='bitacora.php?table=$this->table' title='Bit&aacute;cora ".$this->label_table_plural()."'><img src='$imgPath/bitacora.png' alt='Log' title='Bit&aacute;cora ".$this->label_table_plural()."' /><br />Log<br />".$this->label_table_plural()."</a>")
2819                ,'close'=>array('condition'=>"return ((\$h=='e' || \$h=='a'|| \$h=='r') && !empty(\$id));", 'TDid'=>'iac_cardex_close', 'html'=>"<a href='#' onclick='iac_cardex_window_close(\"SI\");' id='iaCloseItem' title='Cerrar ventana para ver el listado'><img src='$imgPath/tache_rojo.png' /><br/>Cerrar <strong>(F4)</strong></a>")
2820            );
2821
2822        } else { // toolbar cuando soy dialog
2823            $rowNumber = param('iarowindex',1); // row actual
2824            if(!is_numeric($rowNumber)) $rowNumber=1;
2825            $rowNum = param('iarn',10000);
2826            $rowTotal = param('iarnA',1); // total de records, aunque no se vean
2827
2828            $rowFirst = param('iarn1',1); // primer rowNumber
2829            $rowLast = param('iarnL',1); // Ultiom rowNumber
2830            $rowPrev = $rowNumber > 1 ? $rowNumber -1 : $rowLast;
2831            $rowNext = $rowNumber >= $rowLast ? $rowFirst : $rowNumber +1;
2832            $rowParams = "&iarn1=$rowFirst&iarnL=$rowLast&iarnA=$rowTotal";
2833            $firstId = "&id=" . param('f') . "&p=" . param('l');
2834            $lastId = "&id=" . param('l') . "&n=" . param('f');
2835            $prevId = "&id=" . param('p') . "&p=" . param('p1');;
2836            $nextId = "&id=" . param('n') . "&n=" . param('n1');;
2837            $prev1Id = "&p=" . param('p1');
2838            $next1Id = "&n=" . param('n1');
2839            //VCA Cheque DD
2840            //Doc2pdf
2841            $doc2pdf_tabla = $this->table;
2842            if(property_exists($this, "CDD") || $this instanceof app_cheque_dd) {
2843                $doc2pdf_tabla = "cheque_dd";
2844            }
2845
2846
2847            $this->toolbar=array(
2848                'useris'=>''
2849                ,'title'=>''
2850                //,'home'=>array('TDstyle'=>'display:none;','TDid'=>'iaToolbarHome','html'=>"<a href='index.php' title='index'><img src='$imgPath/home.png' title='P&aacute;gina principal' alt='Home' /><br/>home</a>")
2851//                ,'home'=>array('html'=>"<a href='../backoffice/index.php' id='iaHome' title='index' class='toolbar_iahome'><img src='$imgPath/home.png' alt='Home' title='P&aacute;gina principal' /><br/>Inicio <strong>(F1)</strong></a>")
2852//                ,'home'=>array('html'=>"<a href='../backoffice/index.php' id='iaHome' class='toolbar_iahome tooltip_toolbar_wohtml' title='P&aacute;gina principal'><img src='../$imgPath/icons/Home.png' alt='Home' /><br/><strong>Inicio</strong></a>")
2853                ,'home'=>array('html'=>"<div id='iaHomeNew' style='position: relative;'><a href='../backoffice/index.php' id='iaHome' class='tooltip_toolbar' title='<div class=\"bold ui_tooltip_grid_notas_modificacion_importante_si\" >Abrir Vitex en otra pestaña</div>' target='_blank'><img src='../$imgPath/icons/Home.png' alt='Home'/></a><br/><a href='../backoffice/index.php' class='tooltip_toolbar toolbar_cheques' title='<div class=\"ui_tooltip_grid_notas_verificacion_completa\">Inicio</div>'><strong>Inicio</strong></a></div>")
2854                ,'list'=>array('TDstyle'=>'display:none;','TDid'=>'iaToolbarList','condition'=>"return \$this->may_list();"
2855                ,'html'=>"<a href='$_SERVER[PHP_SELF]?$params$logParam' title='Listado de ".$this->label_table_plural()."'><img src='$imgPath/listado.png' alt='Listado' title='Listado completo de ".$this->label_table_plural()."' /><br />Listar</a>")
2856
2857                ,'save'=>array('condition'=>"return ((\$h=='e' || \$h=='a') && !empty(\$id) && \$this->may_update() );"
2858                    ,'html'=>$save)
2859                ,'save'=>array('condition'=>"return (\$h=='e' && !empty(\$id) && \$this->may_update() ) || (\$h=='a' && \$this->may_add() );"
2860                    ,'html'=>$save)
2861                ,'save_new'=>array('condition'=>"return (\$h=='e' && !empty(\$id) && \$this->may_update() ) || (\$h=='a' && \$this->may_add() );",'html'=>$saveNew)
2862                ,'edit'=>array('condition'=>"return (\$h=='r' || \$h=='b') && !empty(\$id) && \$this->may_edit();"
2863                    ,'html'=>"<a href='$_SERVER[PHP_SELF]?iah=e&iaid=$this->id$paramAmp$rowParams' title='Editar'><img src='$imgPath/editar.png' alt='Editar' title='Cambiar el registro' /><br />Editar</a>")
2864                ,'read'=>array('condition'=>"return (\$h=='e' || \$h=='b') && !empty(\$id) && \$this->may_read();"
2865                    ,'html'=>"<a href='$_SERVER[PHP_SELF]?iah=r&iaid=$this->id$paramAmp$rowParams' title='Ver'><img src='$imgPath/ver.png' alt='Consultar' title='Ver' /><br />Consultar</a>")
2866                ,'delete_ask'=>array('condition'=>"return (\$h=='r') && !empty(\$id) && \$this->may_delete();"
2867                    ,'html'=>"<a href='$_SERVER[PHP_SELF]?iah=b&iaid=$this->id$paramAmp' title='Solicitar Borrar este registro'><img alt='Borrar' src='$imgPath/borrar.png' title='Solicitar Borrar este registro' /><br />Borrar</a>")
2868                ,'delete'=>array('condition'=>"return (\$h=='b') && !empty(\$id) && \$this->may_delete();"
2869                    ,'html'=>"<a href='$_SERVER[PHP_SELF]?iah=d&iaid=$this->id$paramAmp' title='Confirmar Borrar'><img alt='Confirme Borrar' src='$imgPath/borrar_ok.png' title='Confirmar Borrar'/><br />Confirme borrar</a>")
2870
2871                ,'add'=>array('condition'=>"return (\$h!='a' || \$h=='e' || \$h=='b') && \$this->may_add();"
2872                    ,'html'=>"<a href='$_SERVER[PHP_SELF]?iah=a$paramAmp$paramAdd' title='¡Alta o crear un nuevo ".$this->label."!'><img alt='Alta' src='../img/icons/New.png' title='Crear un nuevo registro' /><br />Alta</a>")
2873
2874                //copy
2875                ,'export_cardex'=>array('condition'=>"return (\$h!='a' && \$h!='i' ) && !empty(\$id)  && \$this->may_export();"
2876                    ,'html'=>"<a target='_blank' href='$_SERVER[PHP_SELF]?iah=export&iaid=$this->id$paramAmp' title='Exportar'><img src='$imgPath/export.png' alt='Exportar' title='Exportar' />Exportar</a>")
2877                ,'print'=>array('condition'=>"return false && (\$h=='r' || \$h=='b' ) && !empty(\$id)  && \$this->may_print();"
2878                    ,'html'=>"<a href='$_SERVER[PHP_SELF]?iah=print$paramAmp' title='Imprimir'><img src='../$imgPath/icons/printer.png' alt='Imprimir' title='Imprimir' /></a>")
2879
2880                /* \$this->table == 'cheque' || \$this->table == 'compra' || \$this->table == 'pagare' || \$this->table == 'vale' || \$this->table == 'iac_usr' || \$this->table == 'iac_parametros' || \$this->table == 'movimientos' || \$this->table == 'nota_bodega'
2881                <a href='javascript:void(0);' onclick='print_nota();' title='Print' target='_self'><img src='../img/icons/printer.png' alt='Print' title='Print' /><br/><strong>Print</strong></a>
2882                */
2883/*            ,'new_print'=>array('condition'=>"return (\$h=='r' || \$h=='b' || \$h=='e' || \$h=='s') && !empty(\$id) && (\$this->table == 'vale');"
2884                ,'html'=>"<a href='#' onclick='ia_imprime_doc();' id='ianew_print' title=''><img src='../img/icons/printer.png' alt='Print' title='Print' /><br /><strong>Print</strong></a>")*/
2885
2886            ,'pdf'=>array('condition'=>"return (\$h=='r' || \$h=='b' || \$h=='e' || \$h=='s') && !empty(\$id) && (\$this->table == 'compra' || \$this->table == 'iac_usr' || \$this->table == 'iac_parametros' || \$this->table == 'movimientos' || \$this->table == 'nota_bodega');"
2887                ,'html'=>"<a href='#' onclick='opcionesDePDF(\"$doc2pdf_tabla\", \"$this->id\");' id='iaDoc2PDF' title='Generar PDF'><img src='$imgPath/pdf_file.png' alt='Generar PDF' title='Generar PDF' /><br /><strong>PDF</strong></a>")
2888
2889            ,'img'=>array('condition'=>"return (\$h=='r' || \$h=='b' || \$h=='e' || \$h=='s') && !empty(\$id) && (\$this->table == 'compra' || \$this->table == 'iac_usr' || \$this->table == 'iac_parametros' || \$this->table == 'movimientos' || \$this->table == 'nota_bodega');"
2890                ,'html'=>"<a href='#' onclick='opcionesDePDF(\"$doc2pdf_tabla\", \"$this->id\",\"\",\"JPG\");' id='iaDoc2PDF' title='Generar JPG'><img src='../img/icons/Pictures.png' alt='Generar JPG' title='Generar JPG' /><br /><strong>JPG</strong></a>")
2891
2892
2893            ,'new_pdf'=>array('condition'=>"return (\$h=='r' || \$h=='b' || \$h=='e' || \$h=='s') && !empty(\$id) && (\$this->table == 'cheque' || \$this->table == 'vale' || \$this->table == 'pagare');"
2894                ,'html'=>"<a href='#' onclick='exporter.pdf_table();' id='iaDoc2PDF' title='Generar PDF'><img src='$imgPath/pdf_file.png' alt='Generar PDF' title='Generar PDF' /><br /><strong>PDF</strong></a>")
2895
2896            ,'new_img'=>array('condition'=>"return (\$h=='r' || \$h=='b' || \$h=='e' || \$h=='s') && !empty(\$id) && (\$this->table == 'cheque' || \$this->table == 'vale' || \$this->table == 'pagare');"
2897                ,'html'=>"<a href='#' onclick='exporter.imageSave();' id='iaDoc2JPG' title='Generar JPG'><img src='../img/icons/Pictures.png' alt='Generar JPG' title='Generar JPG' /><br /><strong>JPG</strong></a>")
2898
2899            ,'new_copy_image'=>array('condition'=>"return (\$h=='r' || \$h=='b' || \$h=='e' || \$h=='s') && !empty(\$id) && (\$this->table == 'cheque' || \$this->table == 'vale' || \$this->table == 'pagare');"
2900                ,'html'=>"<a href='#' onclick='exporter.imageCopy();' id='iaCopyJPG' title='Copiar JPG'><img src='../img/icons/Paste.png' alt='Copiar JPG' title='Copiar JPG' /><br /><strong>Copy JPG</strong></a>")
2901
2902                ,'pdfMasivo'=>array('condition'=>"return (\$this->table == 'iac_usr' && empty(\$id));"
2903                    ,'html'=>"<a href='#' onclick='opcionesDePDF(\"$doc2pdf_tabla\", \"$this->id\");' id='iaDoc2PDF' title='Generar PDF Masivo'><img src='$imgPath/pdf_file.png' alt='Generar PDF Masivo' title='Generar PDF Masivo' /><br /><strong>PDF<br/>Masivo</strong></a>")
2904
2905                ,'log'=>array('condition'=>"return (\$h=='r' || \$h=='b' || \$h=='e') && !empty(\$id) && \$this->may_viewLog();"
2906                    ,'html'=>"<a href='bitacora.php?table=$this->table&record=$this->id' title='Bit&aacute;cora' target='_blank'><img alt='Log' src='$imgPath/bitacora.png' title='Bit&aacute;cora del registro' /><br />Bit&aacute;cora</a>")
2907//onclick='iac_cardex_window_next(window.opener.$cardex_grid,0,\"$this->id\");'
2908// style='visibility: hidden;'
2909                ,'first'=>array( 'condition'=>"return \$h!='a' && \$h!='i';",  'TDid'=>'iac_cardex_first','html'=>"<a class='cardxNav'  href='$_SERVER[PHP_SELF]?iah=$this->h$paramAmp&iarowindex=$rowFirst$rowParams$firstId' rel='opener refferer' title='Ir al primer $this->label #$rowFirst / $rowLast'><img src='../$imgPath/icons/First.png' alt='Primero' /><br />Primer</a>" )
2910                ,'prev'=>array( 'condition'=>"return \$h!='a' && \$h!='i';", 'TDid'=>'iac_cardex_prev','html'=>"<a class='cardxNav'  href='$_SERVER[PHP_SELF]?iah=$this->h$paramAmp&iarowindex=$rowPrev$rowParams$prevId$prev1Id' rel='opener refferer' title='Ir al $this->label anterior #$rowPrev / $rowLast'><img src='../$imgPath/icons/Back.png' alt='Anterior' /><br />Anterior</a>" )
2911                ,'next'=>array( 'condition'=>"return \$h!='a' && \$h!='i';", 'TDid'=>'iac_cardex_next', 'html'=>"<a class='cardxNav'   href='$_SERVER[PHP_SELF]?iah=$this->h$paramAmp&iarowindex=$rowNext$rowParams$nextId$next1Id' rel='opener refferer' title='Ir al siguiente $this->label #$rowNext / $rowLast'><img alt='Siguiente' src='../$imgPath/icons/Forward.png' /><br />Siguiente</a>" )
2912                ,'last'=>array( 'condition'=>"return \$h!='a' && \$h!='i';", 'TDid'=>'iac_cardex_last', 'html'=>"<a class='cardxNav'   href='$_SERVER[PHP_SELF]?iah=$this->h$paramAmp&iarowindex=$rowLast$rowParams$lastId' rel='opener refferer' title='Ir al Ultimo $this->label #$rowLast / $rowLast'><img alt='Ultimo' src='../$imgPath/icons/Last.png' /><br />&Uacute;ltimo</a>" )
2913                ,'close'=>array( 'TDid'=>'iac_cardex_close', 'html'=>"<a href='#' onclick='iac_cardex_window_close(\"SI\");' id='iaCloseItem' title='Cerrar ventana para ver el listado'><img src='../$imgPath/icons/Close.png' /><br/>Cerrar <strong>(F4)</strong></a>")
2914
2915            );
2916            $this->jsvars .= "<script>
2917                var iac_cardex_window_has=true, 
2918                iac_cardex_window_grid=window.opener==null ? null : window.opener.$cardex_grid
2919                iac_cardex_window_id=\"$this->id\",
2920                iac_cardex_window_rn='$rowNumber',
2921                iac_modo=\"$this->modo\",
2922                iac_id=\"$this->id\"
2923                ,iac_form_id=\"$this->formId\"; 
2924                </script>";
2925        }
2926
2927       if($this->table === 'cheque') {
2928            $this->toolbar['add'] = [
2929                'condition'=>"return (\$h!='a' || \$h=='e' || \$h=='b') && \$this->may_add()  && !(\$this->modo=='jqgrid_form'  || \$this->modo=='jqgrid_inline');"
2930                ,'html'=>
2931                    "Alta de:<br><a rel='opener refferer' 
2932                        href='$_SERVER[PHP_SELF]?iah=a$paramAmp&CDD=SI'$target id='iaNewItem' 
2933                        title='Nueva Nota!' class='toolbar_generico' style='text-decoration: none'><b style='text-decoration: underline' class='toolbar_bancos'>NOTA</b></a>" .
2934                    "&nbsp;&nbsp;<a rel='opener refferer' 
2935                        href='$_SERVER[PHP_SELF]?iah=a$paramAmp&CDD=NO'$target id='iaNewItem2' 
2936                        title='Nuevo Cheque' class='toolbar_generico' style='text-decoration: none'><b style='text-decoration: underline' class='toolbar_cheques'>CHEQUE</b></a>"
2937                ];
2938
2939          }
2940    }
2941
2942    /**
2943     * iacase::display_toolbar()
2944     *
2945     * @param string $h valor toca hacer normalmente param iah
2946     * @param mixed $cambia
2947     * @return
2948     */
2949    function display_toolbar($h = null,$cambia = [],$doDiv = true, $toolBarClass = 'iactoolbar') {
2950        if($h==null)
2951            $h=$this->h;
2952        if(!empty($cambia)) foreach($cambia as $k=>$v)
2953            $this->toolbar[$k]=$v;
2954        $id=$this->id;
2955
2956        $iah = param('iah', '');
2957
2958        $doEntities = true;
2959        $extraTitle = '';
2960        if(property_exists($this, 'tbhtml') && $this->tbhtml == true)
2961            $doEntities = false;
2962        $extraTitle = array_key_exists('label_plural_extra', $this->table_info) ? $this->table_info['label_plural_extra'] : '';
2963
2964        //echo $doEntities ? 'SI':'NO' . "<br>";
2965        if(array_key_exists('title',$this->toolbar) ) {
2966            if(!is_array($this->toolbar['title']) && $this->toolbar['title']=='' ) {
2967                $this->toolbar['title']=array();
2968                $toolbarTitle = property_exists($this, "toolbarTitle") ? $this->toolbarTitle : "toolbarTitle";
2969                $moneda = "";
2970
2971                if($toolbarTitle != "toolbarTitleChequeDD") {
2972                    $moneda = array_key_exists("moneda_id", $this->values) ? $this->values['moneda_id'] : "";
2973                    $moneda = $moneda == 1 ? 'PESOS' : ($moneda == 2 ? 'USD' : '');
2974
2975                }
2976                $toolbarTitleClass = $toolbarTitle . $moneda;
2977
2978
2979
2980                $this->toolbar['title']['TDclass'] = $toolbarTitleClass;
2981                $this->toolbar['title']['TDid'] = $toolbarTitle;
2982                if($h === '' || $h === 'l')
2983                    $this->toolbar['title']['html']="<div class=toolbarTitle>".($doEntities ? ia_htmlentities($this->label_list().$extraTitle) : $this->label_list().$extraTitle)."</div>";
2984                elseif($h === 'qbe' )
2985                    $this->toolbar['title']['html']="<div class=toolbarTitle>Buscar ".($doEntities ? ia_htmlentities($this->label_list().$extraTitle) : $this->label_list().$extraTitle)."</div>";
2986                elseif($h === 'qbr' )
2987                    $this->toolbar['title']['html']="<div class=toolbarTitle>".($doEntities ? ia_htmlentities($this->label_list().$extraTitle) : $this->label_list().$extraTitle)." encontrados</div>";
2988                elseif($h === 'a')
2989                    $this->toolbar['title']['html']="<div class=toolbarTitle>".($doEntities ? ia_htmlentities($this->label_add().$extraTitle) : $this->label_add().$extraTitle)."</div>";
2990                elseif($h === 'e' || $h === 'r' || $h === 'b') {
2991                    //2016-06-15 iarnL iarnA
2992                    $tmpRow = param('iarowindex');
2993                    $rowLast = param('iarnL'); // Ultiom rowNumber
2994                    if(!empty($tmpRow) && !empty($rowLast))
2995                        $tmpRow = "$tmpRow/$rowLast";
2996                    $this->toolbar['title']['html']="<div class=toolbarTitle id=toolBarSummary><span>".$this->label_record_summary()."</span><br><span id=iac_cardex_rn style='color:red'>".(empty($tmpRow) ? '' : " #$tmpRow")."</span></div>";
2997                }
2998                $this->toolbar['title']['TDstyle']="width:380px;";
2999
3000           }  elseif(!is_array($this->toolbar) && $this->toolbar['title']!='' ) {
3001                $tmp=$this->toolbar['title'];
3002                $this->toolbar['title']=array('html'=>$tmp);
3003
3004           }
3005        }
3006
3007        $menu_toolbar_select = $this->toolbar['menu_toolbar_select'] ?? '';
3008        if (isset($this->toolbar['menu_toolbar_select']))
3009            unset($this->toolbar['menu_toolbar_select']);
3010
3011        $text_align="text-align: left";
3012        if (empty($menu_toolbar_select))
3013            $text_align = '';
3014
3015        if($doDiv)
3016            echo "<div class='$toolBarClass' id='iactoolbar'>";
3017        echo "<style>#iactoolbarselect {} #iactoolbarselect a {text-decoration: none;}</style><table class=iactoolbar id=iactoolbartable style='height: 81px;'><tr><td id='iactoolbarselect' style='min-width:134px; width:160px; $text_align'>$menu_toolbar_select</td>".PHP_EOL;
3018        $puedeCobranza = tiendas_puede_consultar(cual: 'cobranza');
3019
3020        foreach($this->toolbar as $k=>$v) if(!empty($v)) {
3021            if(is_array($v)) {
3022                switch ($k) {
3023                    case 'home':
3024                        if(Permisador::puede_consultar_permisos() && !str_contains($_SERVER['REQUEST_URI'], 'verificacion')) {
3025                            echo "<td style='vertical-align:text-top'>";
3026                            echo "<span id='permisosPorHoja' title='Activa Ver/Editar Permisos de esta Hoja' class='ui-icon ui-icon-key tooltip_toolbar_wohtml' style=\"cursor:pointer;display:none\"></span>";
3027                            echo "<span id='permisosPorParte' onclick='permisador.ponPermisoParte();' title='Activa Ver/Editar los Permisos Especificos' class='ui-icon ui-icon-key tooltip_toolbar' style=\"cursor:pointer;display:none\"></span>";
3028
3029                            if($this->table === "clientes_saldos_live")
3030                                echo "<i id='lock-btn' class='fa-regular fa-gear-complex pointer' data-divparam='dab_parametros' data-titulo='Parametros Clientes Saldos' data-subtema='clientes_saldos' title='Parámetros para Clientes Saldos' onclick='iacParam.edit(\"clientes_saldos.html\");' style='cursor: pointer;'></i>";
3031                        }
3032                        break;
3033                    case 'doc': continue 2; break;
3034                    case 'cheques':
3035                        if($puedeCobranza || tiendas_puede_consultar(cual: 'cheque'))
3036                            break;
3037                        continue 2;
3038                    case 'pagares':
3039                        if($puedeCobranza || tiendas_puede_consultar(cual: 'pagare'))
3040                            break;
3041                        continue 2;
3042                    case 'vales':
3043                        if($puedeCobranza)
3044                            break;
3045                        continue 2;
3046                    case 'bancos':
3047                        if(puedeCuentaBancaria()['puede'])
3048                            break;
3049                        continue 2;
3050                    case 'log':
3051                    case 'log_all':
3052                    case 'logall':
3053                        if(usuarioTipoRony())
3054                            break;
3055                        continue 2;
3056                }
3057
3058                $TDelemId=array_key_exists('TDid',$v) ? " id=$v[TDid] " : '';
3059                $TDstyle=array_key_exists('TDstyle',$v) ? " style='$v[TDstyle]'" : '';
3060                $TDclass=array_key_exists('TDclass',$v) ? " class='$v[TDclass]'" : '';
3061
3062                if(array_key_exists('condition',$v) ) {
3063//echo "<pre>$k=".print_r($v,true)."</pre>";
3064                    $tmpcond=eval($v['condition']);
3065                    if(!$tmpcond ) {
3066                        continue;
3067                    }
3068                }
3069                if(array_key_exists('html',$v)) {
3070                    echo "<td " . ($k === "ctasT" ? "style='width: 280px;'" : ($k === "useris" ? "style='width: 180px;'" : "")) . "$TDelemId$TDstyle>$v[html]";
3071                }
3072                if(array_key_exists('function',$v)) {
3073                    echo "<td $TDelemId $TDclass $TDstyle>";
3074                    $v['function']();
3075                    echo PHP_EOL;
3076                    continue;
3077                }
3078            } else
3079                echo "<td>$v";
3080        }
3081        echo "</table></div><div id='iactoolbarspacer' style='height: 79px;'></div>".PHP_EOL;
3082
3083        echo $this->jsvars;
3084        echo $this->jsscripts;
3085
3086echo "<script>try{/*if(document.getElementById('iactoolbarspacer') && document.getElementById('iactoolbar')) document.getElementById('iactoolbarspacer').style.height=(document.getElementById('iactoolbartable').offsetHeight-5)+'px';*/ $('#iactoolbartable').css('width', window.innerWidth - 20);} catch(er) {console.log('toolbarheight error al table toolbar ponerle id iactoolbartable',er);}</script>";
3087    }
3088
3089////////////////////////////////////////////////////
3090// Permisos
3091//
3092////////////////////////////////////////////////////
3093    /**
3094     * iacase::sin_permiso()
3095     *
3096     * @param string $h
3097     * @return boolean
3098     */
3099    function sin_permiso($h='') {
3100        $this->h='sinpermiso';
3101        $this->msg_err="¡Sin permiso!";
3102        $this->msg_aviso="¡Sin permiso!";
3103        $this->msg_show();
3104        return false;
3105    }
3106
3107    /**
3108     * iacase::h_a_permiso()
3109     *
3110     * @param string $h
3111     * @return string
3112     */
3113    function h_a_permiso($h='') {
3114        if(empty($h))
3115            $h=$this->h;
3116         if($h=='a' || $h=='i')
3117            return 'insertar';
3118         if($h=='e' || $h=='s')
3119            return 'cambiar';
3120         if($h=='b' || $h=='d')
3121            return 'borrar';
3122         return 'ver';
3123    }
3124
3125    /**
3126     * iacase::may_add()
3127     * Permiso para ver la forma de dar alta
3128     * @return  boolean TRUE puede, false no puede
3129     */
3130    function may_add() { return $this->permiso_insert; }
3131    /**
3132     * iacase::may_insert()
3133     * Permiso para dar altas, insert
3134     * @return boolean TRUE puede, false no puede
3135     */
3136    function may_insert() { return $this->may_add(); }
3137    /**
3138     * iacase::may_edit()
3139     * Permiso para ver la forma de editar
3140     * @return boolean
3141     */
3142    function may_edit() { return $this->permiso_update; }
3143    /**
3144     * iacase::may_update()
3145     * Permiso para hacer el update
3146     * @return boolean TRUE puede, false no puede
3147     */
3148    function may_update() { return $this->may_edit() && ($this->asChild ? $this->asChild_update : true); }
3149    /**
3150     * iacase::may_delete()
3151     * Parmiso para borrar, se usa en confirmar y en borrar.
3152     * @return boolean TRUE puede, false no puede
3153     */
3154    function may_delete() { return $this->permiso_delete && ($this->asChild ? $this->asChild_delete : true); }
3155    /**
3156     * iacase::may_read()
3157     * Permiso para ver el record
3158     * @return boolean TRUE puede, false no puede
3159     */
3160    function may_read() { return $this->permiso_read; }
3161    /**
3162     * iacase::may_list()
3163     * Permiso para listar los records
3164     * @return boolean TRUE puede, false no puede
3165     */
3166    function may_list() { return $this->permiso_list; }
3167    /**
3168     * iacase::may_export()
3169     * Permiso para exportar
3170     * @return boolean TRUE puede, false no puede
3171     */
3172    function may_export() { return $this->permiso_export; }
3173    /**
3174     * iacase::may_print()
3175     * Permiso para imprimir
3176     * @return boolean TRUE puede, false no puede
3177     */
3178    function may_print() { return $this->may_export(); }
3179    /**
3180     * iacase::may_viewLog()
3181     * Permiso para ver el log
3182     * @return boolean TRUE puede, false no puede
3183     */
3184    function may_viewLog() { return $this->permiso_export; }
3185    /**
3186     * iacase::permiso_por_record()
3187     * Cambia los permisos habiendo leido el record en $this->enDB
3188     * @return void
3189     */
3190    function permiso_por_record() { }
3191    /**
3192     * iacase::permiso_por_tabla()
3193     *
3194     * @param string $h
3195     * @param string $section
3196     * @param mixed $enDB
3197     * @return
3198     */
3199    function permiso_por_tabla($h='',$section='',$enDB=null) { return;
3200    /*
3201    global $PERMISOS_APP;
3202        if(empty($h))
3203            $h=$this->h;
3204
3205        // tabla especial
3206        if($this->table=='iac_table' || $this->table=='iac_log_hecho' ) {
3207            if( array_key_exists('tipo',$_SESSION) && ($_SESSION['tipo']=='Administrador' || $_SESSION['tipo']=='Super user' ) ) {
3208                $this->permiso_export=$this->permiso_list=$this->permiso_read=true;
3209                $this->permiso_delete=$this->permiso_insert=$this->permiso_update=false;
3210            } else {
3211                $this->permiso_export=$this->permiso_list=$this->permiso_read=false;
3212                $this->permiso_delete=$this->permiso_insert=$this->permiso_update=false;
3213            }
3214            return;
3215        }
3216
3217        // es power user;
3218        if( array_key_exists('tipo',$_SESSION) && ($_SESSION['tipo']=='Administrador' || $_SESSION['tipo']=='Super user' ) ) {
3219            if($this->table=='iac_log') {
3220                $this->permiso_delete=$this->permiso_export=$this->permiso_list=$this->permiso_read=true;
3221                $this->permiso_insert=$this->permiso_update=false;
3222                return;
3223            }
3224            $this->permiso_delete=$this->permiso_export=$this->permiso_list=$this->permiso_read=true;
3225            $this->permiso_insert=$this->permiso_update=true;
3226            return;
3227        }
3228
3229        // usa permisos generales o hay override en la clase?
3230        if($this->permiso_app==null )
3231            $permiso=$PERMISOS_APP;
3232        else
3233            $permiso=$this->permiso_app;
3234
3235        // usar permisos por tipo de table en iac_usr?
3236        if($permiso & PERMISO_POR_TIPO_TABLA==PERMISO_POR_TIPO_TABLA) {
3237            if($this->table=='iac_usr' || $this->table_info['es']=='admin') {
3238                $this->permiso_list=array_key_exists('admin_list',$_SESSION) && $_SESSION['admin_list']=='Si';
3239                $this->permiso_read=array_key_exists('admin_read',$_SESSION) && $_SESSION['admin_read']=='Si';
3240                $this->permiso_export=array_key_exists('admin_export',$_SESSION) && $_SESSION['admin_export']=='Si';
3241                $this->permiso_insert=array_key_exists('admin_insert',$_SESSION) && $_SESSION['admin_insert']=='Si';
3242                $this->permiso_update=array_key_exists('admin_update',$_SESSION) && $_SESSION['admin_update']=='Si';
3243                $this->permiso_delete=array_key_exists('admin_delete',$_SESSION) && $_SESSION['admin_delete']=='Si';
3244            } elseif($this->table_info['es']=='log') {
3245                $this->permiso_export=$this->permiso_list=$this->permiso_read=array_key_exists('log_view',$_SESSION) && $_SESSION['log_view']=='Si';
3246                $this->permiso_delete=array_key_exists('log_delete',$_SESSION) && $_SESSION['log_delete']=='Si';
3247                $this->permiso_insert=$this->permiso_update=false;
3248                return;
3249            } elseif($this->table_info['es']=='catalog') {
3250                $this->permiso_list=array_key_exists('catalogo_list',$_SESSION) && $_SESSION['catalogo_list']=='Si';
3251                $this->permiso_read=array_key_exists('catalogo_read',$_SESSION) && $_SESSION['catalogo_read']=='Si';
3252                $this->permiso_export=array_key_exists('catalogo_export',$_SESSION) && $_SESSION['catalogo_export']=='Si';
3253                $this->permiso_insert=array_key_exists('catalogo_insert',$_SESSION) && $_SESSION['catalogo_insert']=='Si';
3254                $this->permiso_update=array_key_exists('catalogo_update',$_SESSION) && $_SESSION['catalogo_update']=='Si';
3255                $this->permiso_delete=array_key_exists('catalogo_delete',$_SESSION) && $_SESSION['catalogo_delete']=='Si';
3256            } elseif($this->table_info['es']=='process') {
3257                $this->permiso_list=array_key_exists('process_list',$_SESSION) && $_SESSION['process_list']=='Si';
3258                $this->permiso_read=array_key_exists('process_read',$_SESSION) && $_SESSION['process_read']=='Si';
3259                $this->permiso_export=array_key_exists('process_export',$_SESSION) && $_SESSION['process_export']=='Si';
3260                $this->permiso_insert=array_key_exists('process_insert',$_SESSION) && $_SESSION['process_insert']=='Si';
3261                $this->permiso_update=array_key_exists('process_update',$_SESSION) && $_SESSION['process_update']=='Si';
3262                $this->permiso_delete=array_key_exists('process_delete',$_SESSION) && $_SESSION['process_delete']=='Si';
3263            } else {
3264                $this->permiso_list=array_key_exists('data_list',$_SESSION) && $_SESSION['data_list']=='Si';
3265                $this->permiso_read=array_key_exists('data_read',$_SESSION) && $_SESSION['data_read']=='Si';
3266                $this->permiso_export=array_key_exists('data_export',$_SESSION) && $_SESSION['data_export']=='Si';
3267                $this->permiso_insert=array_key_exists('data_insert',$_SESSION) && $_SESSION['data_insert']=='Si';
3268                $this->permiso_update=array_key_exists('data_update',$_SESSION) && $_SESSION['data_update']=='Si';
3269                $this->permiso_delete=array_key_exists('data_delete',$_SESSION) && $_SESSION['data_delete']=='Si';
3270            }
3271        }
3272
3273        // usar permisos por table, de estar en iac_table_permission
3274        if($permiso & PERMISO_POR_TABLE_PERMISSIONS==PERMISO_POR_TABLE_PERMISSIONS) {
3275            $puede=ia_singleton("SELECT ".SQL_CACHE."* FROM iac_table_permission WHERE iac_table=".strit($this->table)." AND iac_usr_id=".strit($this->usuario_id)." LIMIT 1");
3276            if($puede) {
3277                $this->permiso_list=$puede['data_list']=='Si';
3278                $this->permiso_read=$puede['data_read']=='Si';
3279                $this->permiso_export=$puede['data_export']=='Si';
3280                $this->permiso_insert=$puede['data_insert']=='Si';
3281                $this->permiso_update=$puede['data_update']=='Si';
3282                $this->permiso_delete=$puede['data_delete']=='Si';
3283            }
3284        }
3285
3286    */
3287    }
3288
3289    /**
3290     * iacase::permiso_por_campo()
3291     *
3292     * @param string $h
3293     * @param string $seccion
3294     * @param mixed $enDB
3295     * @return
3296     */
3297    function permiso_por_campo($h='',$seccion='',$enDB=null) { return;
3298    /*
3299        //falta if superuser return
3300        if(empty($h))
3301            $h=$this->h;
3302
3303        $arr=ia_sqlArray("SELECT campo,ver_dato,insertar_dato,cambiar_dato FROM iac_field_permission WHERE iac_table=".strit($this->table_id)." AND iac_usr_id=$this->usuario_id",'campo');
3304        if(empty($arr))
3305            return;
3306        foreach($arr as $fieldName=>$p) {
3307            if($h=='a' || $h=='i') {
3308                if( $p['insertar_dato']==0 && array_key_exists($fieldName,$this->campos) )
3309                    $this->campos[$fieldName]['modo']='Nada';
3310            }
3311            elseif($h=='e' || $h=='s') {
3312                if( $p['cambiar_dato']=='No' && array_key_exists($fieldName,$this->campos) )
3313                    if($p['ver_dato']==0)
3314                        $this->campos[$fieldName]['modo']='Nada';
3315                    else
3316                        $this->campos[$fieldName]['modo']='R/W';
3317            }
3318            elseif($p['ver_dato']==0 && array_key_exists($fieldName,$this->campos) )
3319                $this->campos[$fieldName]['modo']='Nada';
3320        }
3321    */
3322    }
3323
3324    /**
3325     * iacase::puedo_base()
3326     *
3327     * @param string $h valor toca hacer normalmente param iah
3328     * @param string $id
3329     * @return
3330     */
3331    function puedo_base($h=null,$id=null) {
3332        if(empty($h))
3333            $h=$this->h;
3334        $this->permiso_por_tabla($h);
3335        if($h=='a' || $h=='i')
3336            return $this->permiso_insert;
3337        if($h=='e' || $h=='s')
3338            return $this->permiso_update;
3339        if($h=='b' || $h=='d')
3340            return $this->permiso_delete;
3341        if($h=='r')
3342            return $this->permiso_read;
3343        return $this->permiso_list;
3344    }
3345
3346    /**
3347     * iacase::puedo_campo()
3348     *
3349     * @param string $fieldName nombre del campo
3350     * @param string $id
3351     * @param string $h valor toca hacer normalmente param iah
3352     * @return
3353     */
3354    function puedo_campo($fieldName,$id=null,$h=null) {
3355        if(empty($h))
3356            $h=$this->h;
3357        $p=$this->campo_key($fieldName,'modo','R/W');
3358        // falta regresar Nada, R/O, R/W
3359        return $p;
3360    }
3361
3362////////////////////////////////////////////////////
3363//
3364//
3365////////////////////////////////////////////////////
3366
3367
3368////////////////////////////////////////////////////
3369// field''s label tag
3370// FALTA comments
3371////////////////////////////////////////////////////
3372    /**
3373     * iacase::title_tag()
3374     *
3375     * @param string $fieldName nombre del campo
3376     * @return
3377     */
3378    function title_tag($fieldName) {
3379        if(array_key_exists($fieldName,$this->campos) && array_key_exists('title',$this->campos[$fieldName]) && !empty($this->campos[$fieldName]['title']) )
3380            return ' title="'.ia_htmlentities($this->campos[$fieldName]['title']).'"';
3381        // falta sanitize to label
3382        //VCA
3383        //return ' title="'.ia_htmlentities($fieldName).'"';
3384        if(array_key_exists('label',$this->campos[$fieldName]))
3385            return ' title="'.ia_htmlentities($this->campos[$fieldName]['label']).'"';
3386        else
3387            return ' title="'.ia_htmlentities($this->to_label($fieldName)).'"';
3388
3389    }
3390
3391    /**
3392     * iacase::label_tag()
3393     *
3394     * @param string $fieldName nombre del campo
3395     * @param mixed $label
3396     * @param string $prefijo
3397     * @param string $sufijo
3398     * @param array $atributes
3399     * @param string $modo Nada, R/O, R/W
3400     * @return
3401     */
3402    function label_tag($fieldName,$label=null,$prefijo='',$sufijo='',$atributes=array(),&$modo=null) {
3403        if($modo==null)
3404            $modo=$this->puedo_campo($fieldName);
3405        if($modo=='Nada')
3406            return '';
3407        $mark='';$extra_label='';
3408        if( $this->h=='e' || $this->h=='a'  || $this->h=='r') {
3409            if($this->h!='r')
3410                $mark=$this->label_optional_mark;
3411            if( array_key_exists($fieldName,$this->campos) ) {
3412                $campo=$this->campos[$fieldName];
3413                if(array_key_exists('label_class',$campo))
3414                    $this->atribute_setIfNotExists('class',$campo['label_class'],$atributes);
3415                else
3416                    $this->atribute_setIfNotExists('class',$this->label_class,$atributes);
3417                $type=array_key_exists('Type', $campo)? $campo['Type'] : 'varchar';
3418                $doReq=true;
3419                if( ($type =='enum' || $type=='set') && !$campo['Null'] )
3420                    $doReq=false;
3421                elseif( substr($fieldName,-3)=='_id' && !$campo['Null'] )
3422                    $doReq=false;
3423                if($this->h!='r' && $doReq && array_key_exists('required',$this->campos[$fieldName]) && $this->campos[$fieldName]['required'] ) {
3424                    $mark=$this->label_required_mark;
3425                    //if($this->label_required_class!='')
3426                    //    $this->atribute_set('class',$this->label_required_class,$atributes,true,' ');
3427                }
3428                if( array_key_exists('conerror',$this->campos[$fieldName]) && !empty($this->campos[$fieldName]['conerror']) ) {
3429                    $this->atribute_set('class',$this->label_error_class,$atributes);
3430                }
3431                //VCA
3432                if(array_key_exists('extra_label',$campo))
3433                    $extra_label=$campo['extra_label'];
3434            }
3435        }
3436        $tag='';
3437        if(!empty($atributes)) foreach($atributes as $attr=>$attrvalue)
3438            $tag.=" $attr=\"$attrvalue\"";
3439        $lbl_field = $modo!='Hidden' ? $this->label_field($fieldName,$label,$prefijo,$sufijo) : "";
3440        return "<label".($this->h=='a' || $this->h=='e' ? " for='$fieldName'" : '' ).$this->title_tag($fieldName)."$tag>$mark".$lbl_field.'</label>'.$extra_label;
3441    }
3442
3443////////////////////////////////////////////////////
3444// letreros para tabla, litado y campos
3445////////////////////////////////////////////////////
3446    /**
3447     * iacase::label_field()
3448     *
3449     * @param string $fieldName nombre del campo
3450     * @param mixed $label
3451     * @param string $prefijo
3452     * @param string $sufijo
3453     * @return
3454     */
3455    function label_field($fieldName,$label=null,$prefijo='',$sufijo='') { // field label
3456        if(empty($label)) {
3457            if(array_key_exists($fieldName,$this->campos) && array_key_exists('label',$this->campos[$fieldName]) && !empty($this->campos[$fieldName]['label']) )
3458                return $prefijo.ia_htmlentities($this->campos[$fieldName]['label']).$sufijo;
3459            if($fieldName==$this->pk_field)
3460                 $prefijo.ia_htmlentities( $this->to_label($fieldName).' Id' ).$sufijo;
3461            return $prefijo.ia_htmlentities( $this->to_label($fieldName) ).$sufijo;
3462        }
3463        return ia_htmlentities($label);
3464    }
3465    /**
3466     * iacase::label_record()
3467     * Nombre corto del registro
3468     * @return string el nombre corto del registro
3469     */
3470    function label_record() {
3471        if(array_key_exists('label_field',$this->table_info )) {
3472            $lbl=$this->table_info['label_field'];
3473            if(array_key_exists($lbl,$this->values))
3474                return $this->values[$lbl];
3475            elseif(array_key_exists($lbl,$this->enDB))
3476                return $this->enDB[$lbl];
3477        }
3478        return $this->label;
3479    }
3480    /**
3481     * iacase::label_record_summary()
3482     * Resumen de registro
3483     * @return string el resumen del registro
3484     */
3485    function label_record_summary() {
3486        $label= $this->label_record();
3487        return $this->label .': '. $label;
3488    }
3489    /**
3490     * iacase::label_add()
3491     * Etiqueta para agregar un registro
3492     * @return string la etiqueta para agregar un registro si existe $this->table_info['label_add'], del contrario la arma
3493     */
3494    public function label_add() {
3495        if(array_key_exists('label_add',$this->table_info))
3496            return $this->table_info['label_add'];
3497        $c=substr($this->label,0,-1);
3498        if($c=='a')
3499            return "Alta: ".$this->label;
3500        return "Alta: ".$this->label;
3501    }
3502    /**
3503     * iacase::label_list()
3504     * Etiqueta para el listado
3505     * @return string la etiqueta del listado, si existe $this->table_info['label_list'] del contrario  $this->label_table_plural()
3506     */
3507    public function label_list() {
3508        if(array_key_exists('label_list',$this->table_info))
3509            return $this->table_info['label_list'];
3510        return $this->label_table_plural();
3511    }
3512    /**
3513     * iacase::label_table_singular()
3514     * Etiqueta para la tabla o tipos de registro en singular
3515     * @return string el label de la tabla en singular
3516     */
3517    public function label_table_singular() { return $this->label; }
3518    /**
3519     * iacase::label_table_plural()
3520     * Etiqueta para la tabla o tipos de registro en plural
3521     * @return string el label de la tabla en plural
3522     * @return
3523     */
3524    public function label_table_plural() {
3525        if(array_key_exists('label_plural',$this->table_info))
3526            return $this->table_info['label_plural'];
3527        return to_plural($this->label);
3528    }
3529
3530////////////////////////////////////////////////////
3531// display field value
3532////////////////////////////////////////////////////
3533
3534
3535
3536    /**
3537     * iacase::show()
3538     *
3539     * @param string $fieldName nombre del campo
3540     * @param mixed $value
3541     * @param mixed $editAtributes
3542     * @param mixed $displayAtributes
3543     * @param string $modo Nada, R/O, R/W
3544     * @return
3545     */
3546    function show($fieldName,$value=null,$editAtributes=array(),$displayAtributes=array(),&$modo=null) {
3547        if($modo==null)
3548            $modo=$this->puedo_campo($fieldName);
3549        if($modo=='Nada')
3550            return '';
3551        $tmpModo='R/W';
3552        $campo = $this->campos[$fieldName]??[];
3553        if( $modo=='R/O' && !array_key_exists('readonly',$campo) )
3554            return $this->display($fieldName,$displayAtributes, $value,$modo,true,'log')
3555                .(array_key_exists('hidden_value',$campo) && $campo['hidden_value'] ?
3556              $this->ori_field($fieldName,$this->values[$fieldName],null,$tmpModo).      "<input type='hidden' name='$fieldName' id='$fieldName' value='".ia_htmlentities($this->values[$fieldName])."' />" : ''  );
3557        if($this->h=='a' || $this->h=='e')
3558            return $this->input_auto($fieldName,$editAtributes,$value,$modo);
3559        return $this->display($fieldName,$displayAtributes, $value,$modo,true,'log');
3560    }
3561
3562    /**
3563     * iacase::display()
3564     *
3565     * @param string $fieldName nombre del campo
3566     * @param array $atributes
3567     * @param mixed $value
3568     * @param string $modo Nada, R/O, R/W
3569     * @return
3570     */
3571    function display($fieldName,$atributes=array(),$value=null,&$modo=null,$putLink=true,$enumlogType='') {
3572        //echo $fieldName;
3573
3574        if($modo==null)
3575            $modo=$this->puedo_campo($fieldName);
3576        if($modo==='Nada')
3577            return '';
3578        if($modo==='Hidden')
3579            return '';
3580        if($fieldName==='pwd')
3581            return '';
3582        if( $value===null && array_key_exists($fieldName,$this->values))
3583            $value=$this->values[$fieldName];
3584        $pie_campo=array_key_exists($fieldName,$this->campos) && array_key_exists('pie',$this->campos[$fieldName]) ?  $this->campos[$fieldName]['pie'] : '';
3585        if( $value==='' || $value===null )
3586            return $pie_campo;
3587        if( !$this->primary_key_show && $fieldName==$this->pk_field )
3588            return;
3589        if(array_key_exists($fieldName,$this->campos)) {
3590            
3591            $type = $this->campos[$fieldName]['Type'] ?? 'varchar';
3592            $formato= array_key_exists('formato',$this->campos[$fieldName]) ? $this->campos[$fieldName]['formato'] : '';
3593
3594            if($type=='estado_formatter')
3595                return estado2Html($this->table, $value);
3596
3597            if($type=='asignacion_formatter')
3598                return asignacion_2_html($this->table."_".$fieldName, $value);
3599
3600            if($type=='supervision_formatter')
3601                return asignacion_2_html($this->table."_".$fieldName, $value);
3602
3603            if($type=='enum') {
3604                global $gAppRelate;
3605                $ret = $this->array_val($value, $gAppRelate->enum_get($this->table,$fieldName,array(),$enumlogType),$value);
3606                return empty($enumlogType) ? ia_htmlentities($ret) : $ret;
3607            }
3608
3609            if($type=='set')
3610                return $this->display_set($fieldName,$value).$pie_campo;
3611
3612            if($formato=='checkbox') {
3613                if($type=='char' || $type=='varchar')
3614                    return ia_htmlentities($value).$pie_campo;
3615                return ($value ? 'Si' : 'No').$pie_campo;
3616            }
3617
3618            if(strpos($formato,'link')!==FALSE)
3619                return $this->display_link($fieldName,$value).$pie_campo;
3620
3621            //if($formato!='fckeditor') {
3622                if($formato!='json_file' && is_array($value)) {
3623                    $tmp='';
3624                    foreach($value as $tmpValue)
3625                        $tmp.="<li>".ia_htmlentities($tmpValue);
3626                    $value="<ul>$tmp</ul>";
3627                    return $value.$pie_campo;
3628                }
3629            //} else
3630            //    return '<div class=fck>'.$value.'</div>';
3631
3632            if($this->display_email_link && $formato=='email' && $putLink)
3633                return "<a href='mailto:".ia_htmlentities($value)."'>".ia_htmlentities($value)."</a> $pie_campo";
3634
3635            if($this->display_url_link && $formato=='url') {
3636                $prefijo=array_val('url_prefijo',$this->campos[$fieldName]);
3637
3638                if( substr($value,0,4)!='http' ) {
3639                    $ponHttp="http://".$_SERVER["SERVER_NAME"];
3640                } else
3641                    $ponHttp='';
3642                $corto=array_val('url_id',$this->campos[$fieldName]) ? "<br /><i class=campopie>corto: $ponHttp.$prefijo".$this->id."</i>" : '';
3643                return "<a target='_blank' rel='opener refferer' href='".$ponHttp.$prefijo.$value."'>".ia_htmlentities($ponHttp.$prefijo.$value)."</a>
3644                 $corto
3645                 $pie_campo";
3646            }
3647
3648            if($formato==='anoMes') {
3649                global $gIAData;
3650                if($value=='')
3651                    return '';
3652                $tmp=explode('/',$value);
3653                if(sizeof($tmp)<2)
3654                    $tmp=explode('-',$value);
3655                 if(sizeof($tmp)<2)
3656                    return $value;
3657                if($tmp[0]=='' && $tmp[1]=='')
3658                    return '';
3659                if($tmp[0]=='')
3660                    $tmp[0]='????';
3661                if($tmp[1]=='')
3662                    $tmp[1]='?';
3663                if(is_numeric($tmp[1]))
3664                    $tmp[1]+=0;
3665                if( array_key_exists($tmp[1],$gIAData['monthLong']) )
3666                    return $gIAData['monthLong'][$tmp[1]].', '.$tmp[0];
3667                return $tmp[1].', '.$tmp[0].$pie_campo;
3668            }
3669
3670            if( array_key_exists('numeric',$this->campos[$fieldName]) && $this->campos[$fieldName]['numeric']   ) {
3671                if(is_numeric($value))
3672                    return @number_format($value,$this->campos[$fieldName]['decimales'],($this->campos[$fieldName]['decimales']==0 ? '' : '.'),',').$pie_campo;
3673                else
3674                    return ia_htmlentities( $value).$pie_campo;
3675            }
3676
3677            if($type==='date' || $type==='datetime' || $type==='timestamp' )
3678            {
3679                if($type==='date')
3680                    $value = substr($value, 0, 10);
3681                return ia_htmlentities(mysqlDate2display($value)).$pie_campo;
3682            }
3683
3684            if($type=='bit')
3685                if($value==1 || $value==chr(1)   )
3686                    return $this->bit_field_display['true'].$pie_campo;
3687                else
3688                    return $this->bit_field_display['false'].$pie_campo;
3689
3690            if($type==='longtext' || $type==='mediumtext' || $type==='text') {
3691                //if($formato!='fckeditor' && $enumlogType!='log')
3692                if($enumlogType!='log')
3693                    return "<pre>".ia_htmlentities($value)."</pre>".$pie_campo;
3694                else
3695                    return  html_entity_decode($value).$pie_campo;
3696            }
3697            if($formato==='attachment') {
3698                return $this->display_file_list($fieldName,$atributes,$value).$pie_campo;
3699            }
3700            
3701            if($type==='html' || $formato==='fckeditor') // 2020-07-30 added  || $formato==='fckeditor'
3702                return html_entity_decode($value).$pie_campo; //2020-09-01 se esta guardando en la db con htmlentities
3703
3704            //VCA Inventado
3705            if($type=='json_file'){
3706                return $this->display_json_file_list($fieldName,$atributes,$value).$pie_campo;
3707            }
3708
3709           // if($type=='varchar' || $type=='char' || $type=='year' )
3710           //     return ia_htmlentities($value).$pie_campo;
3711        }
3712        if(in_array(strtolower($fieldName), ['remarks','nota','notas', 'remark', 'comments', 'comment', 'comentario'] ))
3713            return html_entity_decode($value).$pie_campo; //2020-09-01 se esta guardando en la db con htmlentities
3714        return ia_htmlentities($value).$pie_campo;
3715    }
3716
3717    /**
3718     * iacase::display_link()
3719     *
3720     * @param string $fieldName nombre del campo
3721     * @param mixed $value
3722     * @return
3723     */
3724    function display_link($fieldName,$value) {
3725    global $gAppRelate;
3726        $sql=$gAppRelate->sql_link_read($this->table,$fieldName,$value);
3727
3728        // falta display a list or coma seprated?
3729            $tmp=ia_sqlVector($sql);
3730
3731        if( array_key_exists('readonly',$this->campos[$fieldName]) && !empty($this->campos[$fieldName]['readonly']) &&  sizeof($tmp)==1)
3732            return "<input type=text id='$fieldName' READONLY value='".ia_htmlentities($tmp[0])."' size='".strlen($tmp[0])."'/>";
3733        if(!is_array($tmp))
3734            return ia_htmlentities($tmp);
3735        elseif(sizeof($tmp)==1)
3736            return ia_htmlentities($tmp[0]);
3737        elseif(sizeof($tmp)==0)
3738            return '';
3739        $ret='<ul>';
3740        foreach($tmp as $d)
3741            $ret.='<li>'.ia_htmlentities($d);
3742        return $ret.'</ul>';
3743    }
3744
3745    /**
3746     * iacase::display_set()
3747     *
3748     * @param string $fieldName nombre del campo
3749     * @param mixed $value
3750     * @return
3751     */
3752    function display_set($fieldName,$value) {
3753        if(array_key_exists('ul',$this->campos[$fieldName]) && !$this->campos[$fieldName]['ul']) {
3754            if(is_array($value))
3755                return ia_htmlentities ( implode(', ',$value) )  ;
3756            else
3757                return ia_htmlentities ( str_replace(',',', ', $value ) ) ;
3758        }
3759        if(!is_array($value))
3760            $tmp=explode(',',$value);
3761        else
3762            $tmp=$value;
3763
3764        if(!empty($tmp)) {
3765            $ret='<ul>';
3766            foreach($tmp as $d)
3767                $ret.='<li>'.ia_htmlentities($d);
3768            return $ret.'</ul>';
3769        } else
3770            return '';
3771    }
3772
3773    /**
3774     * iacase::display_file_list()
3775     *
3776     * @param string $fieldName nombre del campo
3777     * @param array $atributes
3778     * @param mixed $value
3779     * @param string $modo Nada, R/O, R/W
3780     * @return
3781     */
3782    function display_file_list($fieldName,$atributes=array(),$value=null,&$modo=null) {
3783    global $gIApath;
3784        if(empty($value) && array_key_exists($fieldName,$this->values))
3785            $value=$this->values[$fieldName];
3786        if(empty($value))
3787            return '';
3788        if($this->h=='e' || $this->h=='s' || $this->h=='a' || $this->h=='i'  )
3789            $editable=true;
3790        else
3791            $editable=false;
3792        $tmpTitula='';
3793        $tmp='';
3794        if($this->campos[$fieldName]['file_max_entries']==1) {
3795            $entry=basename($this->values[$fieldName]);
3796            $tmp="$tmpTitula<ul>".($editable ? "<img alt='Delete' title='Marcar las que borrar' src='$gIApath[WebPath]img/tache_rojo_plano.gif' style='width:16px;height:16px;' />" : '' );
3797            if($editable) {
3798                $del="<input type='checkbox' name='ia_atdel[]' value='$fieldName|".$this->values[$fieldName]."' /> ";
3799            } else
3800                $del='';
3801            $tmp.="<li>$del <a title='Ver en nueva ventana' href='".$this->values[$fieldName]."' target='_blank' rel='opener refferer' >";
3802            $fileNamed=substr( $gIApath['DOCUMENT_ROOT'],0,-1).$this->values[$fieldName];
3803            if( file_is_image($this->values[$fieldName]) )
3804                $tmp.=" <img src='".$this->values[$fieldName]."' style='".ia_image_tagsize_fitmax($fileNamed,64,64)."'><br>";
3805            else
3806                $tmp.=" <img src='".file_icon($fileNamed)."' style='width:16px;' /><br>";
3807            return $tmp.$entry."</a><br/><i style='font-size:smaller'>".ia_image_tag_size($fileNamed).'</i></ul>';
3808        }
3809
3810        $dir=$gIApath['DOCUMENT_ROOT']. $this->values[$fieldName];
3811        if(is_file($dir))
3812            $dir=dirname($dir);
3813        if (is_dir($dir) && $handle = opendir($dir)) {
3814                while (false !== ($entry = readdir($handle))) {
3815                    if ($entry != "." && $entry != "..") {
3816                        if($tmp=='')
3817                            $tmp="$tmpTitula<ul>".($editable ? "<img alt='Delete' title='Marcar las que borrar' src='$gIApath[WebPath]img/tache_rojo_plano.gif' style='width:16px;height:16px;' />" : '' );
3818                        if($editable) {
3819                            $del="<input type='checkbox' name='ia_atdel[]' value='$fieldName|".$this->values[$fieldName]."$entry' /> ";
3820                        } else
3821                            $del='';
3822                        $filePath = $this->values[$fieldName].$entry;
3823                        $fileNamed=substr( $gIApath['DOCUMENT_ROOT'],0,-1).$filePath;
3824                        $isImage = file_is_image($fileNamed);
3825                        if(!$isImage)
3826                            $tmp.="<li style='margin-bottom:0.8em;'>$del <a title='Ver en nueva ventana' href='$filePath' target='_blank' rel='opener refferer' ><img src='".file_icon($fileNamed)."' style='width:16px;' /> $entry</a>";
3827                        else
3828                            $tmp.="<li style='margin-bottom:0.8em;'>$del <a title='Ver en nueva ventana' href='$filePath' target='_blank' rel='opener refferer' >$entry <img src='$filePath' style='".ia_image_tagsize_fitmax($fileNamed,64,64)."'></a>";
3829                        //$tmp .="<br/><i style='font-size:smaller'>".ia_image_tag_size($fileNamed).'</i>';
3830
3831                    }
3832                }
3833                closedir($handle);
3834                if($tmp!='')
3835                    $tmp.='</ul>';
3836            }
3837            return $tmp;
3838    }
3839
3840    /**
3841     * iacase::display_json_file_list()
3842     *
3843     * @param string $fieldName nombre del campo
3844     * @param array $atributes
3845     * @param mixed $value
3846     * @param string $modo Nada, R/O, R/W
3847     * @return
3848     */
3849    function display_json_file_list($fieldName,$atributes=array(),$value=null,&$modo=null) {
3850    global $gIApath;
3851        if(empty($value) && array_key_exists($fieldName,$this->values))
3852            $value=$this->values[$fieldName];
3853        if(empty($value))
3854            return '';
3855        if($this->h=='e' || $this->h=='s' || $this->h=='a' || $this->h=='i'  )
3856            $editable=true;
3857        else
3858            $editable=false;
3859        $value = is_array($value) ? json_encode($value) : $value;
3860        $tmp=json_decode($value, true);
3861        $tmpFiles='';
3862        foreach($tmp as $k=>$v)
3863        {
3864            $tmpFiles.="<li> $v[nombre]";
3865        }
3866
3867        //$tmpFiles = strlen($tmpFiles) ? substr($tmpFiles, 0, -2) : "";
3868        return $tmpFiles;
3869    }
3870////////////////////////////////////////////////////
3871// input field value
3872////////////////////////////////////////////////////
3873    /**
3874     * iacase::input_auto()
3875     *
3876     * @param string $fieldName nombre del campo
3877     * @param array $atributes
3878     * @param mixed $value
3879     * @param string $modo Nada, R/O, R/W
3880     * @param mixed $oriValue
3881     * @param bool $forzaEdit
3882     * @return
3883     */
3884    function input_auto($fieldName,$atributes=array(),$value=null,&$modo=null,$oriValue=null,$forzaEdit=false) {
3885    global $gAppRelate,$gIaHeader;
3886        if($modo==null)
3887            $modo=$this->puedo_campo($fieldName);
3888        if($modo=='Nada')
3889            return '';
3890
3891        /**
3892        $atributes = $this->deduce_attributes($fieldName,$atributes=array(),$value=null,&$modo=null,$oriValue=null,$forzaEdit=false);
3893
3894        function deduce_attributes($fieldName,$atributes=array(),$value=null,&$modo=null,$oriValue=null,$forzaEdit=false){
3895            return;
3896        en forma_porstDiv agregar $(data-validation).off(validame).on(validame);
3897        }
3898        **/
3899
3900        $this->agrega_data_validation($fieldName,$atributes,$value,$modo,$oriValue,$forzaEdit);
3901
3902        if(!$forzaEdit && $modo=='R/O' && !array_key_exists('readonly',$this->campos[$fieldName]))
3903            return  $this->display($fieldName,array(),$value,$modo);
3904
3905        $this->set_name_id_and_value($fieldName,$value, $atributes);
3906        $pie_campo='';
3907        if( array_key_exists('pie',$this->campos[$fieldName]??[])  && !empty($this->campos[$fieldName]['pie']) ) {
3908            if(substr($this->campos[$fieldName]['pie'],0,1)=='<')
3909                $pie_campo=$this->campos[$fieldName]['pie'];
3910            else
3911                $pie_campo="<br /><span class=pie_campo>".$this->campos[$fieldName]['pie']."</span>";
3912        }
3913        if( array_key_exists('pie',$atributes) && !empty($atributes['pie']) ) {
3914            $pie_campo="<br /><span class=pie_campo>".$atributes['pie']."</span>";
3915            unset($atributes['pie_campo']);
3916        }
3917
3918        $ret='';
3919        $tmpModo='R/W';
3920        if($this->conOri)
3921            $ret.=$this->ori_field($fieldName,$oriValue,$atributes['name'],$tmpModo);
3922
3923        if(!array_key_exists($fieldName,$this->campos)) {
3924            $this->atribute_setIfNotExists('type','text',$atributes);
3925            return $ret."<input type='text' value='".ia_htmlentities($value)."' ".$this->atribute_toString($atributes)." autocomplete='off' />".$pie_campo;
3926        }
3927        if(strcasecmp('Hidden',$modo)==0)
3928            return "$ret<input type='hidden' value='".ia_htmlentities($value)."' ".$this->atribute_toString($atributes)." autocomplete='off' />";
3929
3930        $type=$this->campo_key($fieldName,'Type');
3931        $formato=$this->campo_key($fieldName,'formato');
3932        $required=$this->campo_key($fieldName,'required');
3933        $formato = $formato ?? "";
3934        if($required!=null && !$forzaEdit)
3935            $this->atribute_set('required','required',$atributes);
3936
3937
3938        if(strpos($formato,'link')!==FALSE) {
3939            //echo "<pre>".print_r($this->campos[$fieldName], true)."</pre>";
3940            if( array_key_exists('readonly',$this->campos[$fieldName]) && !empty($this->campos[$fieldName]['readonly']) )
3941                return $this->display_link($fieldName,$value);
3942            if(array_key_exists('options_sql',$atributes) ) {
3943                $sql=$atributes['options_sql'];
3944                $atributes['options_sql']=null;
3945            } else {
3946
3947                    $sql=null;
3948            }
3949
3950            return $ret.$this->input_link_sql($fieldName,$sql,$value,$atributes,$formato,$modo,false,true).$pie_campo;
3951        }
3952
3953        if($type=='enum') {
3954            return $ret.$this->input_link_array($fieldName,$gAppRelate->enum_getClassed($this->table,$fieldName,$this->campos),$value,$atributes,$formato,$modo,false).$pie_campo;
3955        }
3956
3957        if($type=='set') {
3958            if(!is_array($value))
3959                $value=explode(',',$value);
3960            $this->atribute_remove('value',$atributes);
3961            $this->atribute_setIfNotExists('multiple','multiple',$atributes);
3962            $this->atribute_setIfNotExists('size',$this->select_multiple_size,$atributes);
3963            $atributes['name'].='[]';
3964
3965            return $ret.$this->input_link_array($fieldName,$gAppRelate->enum_getClassed($this->table,$fieldName,$this->campos),$value,$atributes,$formato,$modo,false).$pie_campo;
3966        }
3967
3968        if($formato=='password') {
3969            $atributes['value']='';
3970            $this->atribute_setIfNotExists('type','password',$atributes);
3971            $tmp= "<input ".$this->atribute_toString($atributes)." autocomplete='off' />";
3972            $atributes['name']='pwd2';
3973            $atributes['id']='pwd2';
3974            return $tmp." otra vez: <input ".$this->atribute_toString($atributes)." autocomplete='off'/>".$pie_campo;
3975        }
3976        if($formato=='fckeditor' ) {
3977            if( isset( $gIaHeader->EDITOR_CKEDITOR ) )
3978                $this->atribute_set('class','iackeditor',$atributes,true);
3979            else
3980                $this->atribute_set('class', 'iafck', $atributes, true);
3981                //$this->atribute_set('style','width:98%',$atributes,true,';');}
3982            unset($atributes['value']);
3983            // 2020-07-30 quite ia_htmlentitites
3984            //return $ret."<textarea ".$this->atribute_toString($atributes).">".ia_htmlentities($value)."</textarea>".$pie_campo;
3985            return $ret."<textarea style='style:width:98%; min-height: 220px;' ".$this->atribute_toString($atributes).">".$value."</textarea>".$pie_campo;
3986        }
3987        if($type=='longtext' || $type=='mediumtext' || $type=='text') {
3988            if($type=='longtext') {
3989                $this->atribute_setIfNotExists('cols',$this->textarea_cols,$atributes);
3990                $this->atribute_setIfNotExists('rows',$this->textarea_rows,$atributes);
3991            } elseif($type=='mediumtext') {
3992                $this->atribute_setIfNotExists('cols',$this->medium_textarea_cols,$atributes);
3993                $this->atribute_setIfNotExists('rows',$this->medium_textarea_rows,$atributes);
3994            }elseif($type=='text') {
3995                $this->atribute_setIfNotExists('cols',$this->text_textarea_cols,$atributes);
3996                $this->atribute_setIfNotExists('rows',$this->text_textarea_rows,$atributes);
3997            }
3998            $this->atribute_set('style',$this->textarea_style,$atributes,true,';');
3999            $this->atribute_remove('value',$atributes);
4000            return $ret."<textarea ".$this->atribute_toString($atributes).">".ia_htmlentities($value)."</textarea>".$pie_campo;
4001        }
4002
4003        if($formato=='checkbox' || $type=='bit') {
4004            $this->atribute_setIfNotExists('type','checkbox',$atributes);
4005            if($type=='bit')
4006                $val=1;
4007            else
4008                $val=$fieldName;
4009            if($value==1 || $value==chr(1) )
4010                $sel=' CHECKED="CHECKED" ';
4011            else
4012                $sel='';
4013            $atributes['value']=1;
4014            return $ret. "<input $sel ".$this->atribute_toString($atributes)." autocomplete='off' />".$pie_campo;
4015        }
4016        // file
4017
4018        if($type=='date')
4019            return $ret.$this->input_date($fieldName,$value,$atributes,$modo,false).$pie_campo;
4020
4021        if($type=='datetime'  || $type=='timestamp')
4022            return $ret.$this->input_datetime($fieldName,$value,$atributes,$modo,false).$pie_campo;
4023
4024        if( $this->campo_key($fieldName,'numeric') )
4025            return $ret.$this->input_number($fieldName,$value,$atributes,$modo,false).$pie_campo;
4026
4027        if($formato=='email')
4028            $this->atribute_setIfNotExists('type','email',$atributes);
4029        elseif($formato=='url')
4030            $this->atribute_setIfNotExists('type','text',$atributes);
4031        else
4032            $this->atribute_setIfNotExists('type','text',$atributes);
4033
4034        if($formato=='anoMes') {
4035            return $ret.$this->input_anoMes($fieldName,$value,$atributes,$modo,false).$pie_campo;
4036        }
4037        if($formato=='attachment')
4038            return $this->input_file($fieldName,$value,$atributes,$modo,false).$pie_campo;
4039
4040        $maxlength='';
4041        if( array_key_exists('maxlength',$this->campos[$fieldName]) ) {
4042            $maxlength=$this->campos[$fieldName]['maxlength'];
4043            if($maxlength!='')
4044                $this->atribute_setIfNotExists('maxlength',$maxlength,$atributes);
4045        }
4046
4047        if(!array_key_exists('size',$atributes)) {
4048            if(array_key_exists('size',$this->campos[$fieldName])) {
4049                $size=$this->campos[$fieldName]['size'];
4050                if($size>$this->input_max_size)
4051                    $atributes['size']=$this->input_max_size;
4052                else
4053                    $atributes['size']=$size;
4054            } elseif($maxlength!='') {
4055                if($this->asChild)
4056                    if($maxlength>$this->input_max_size_child)
4057                        $atributes['size']=$this->input_max_size_child;
4058                    else
4059                        $atributes['size']=$maxlength;
4060                else
4061                    if($maxlength>$this->input_max_size)
4062                        $atributes['size']=$this->input_max_size;
4063                    else
4064                        $atributes['size']=$maxlength;
4065            }
4066
4067        }
4068        // $this->atribute_remove('required',$atributes);
4069        return $ret."<input ".$this->atribute_toString($atributes)." autocomplete='off' />$pie_campo";
4070    }
4071
4072    /**
4073     * iacase::input_link_sql()
4074     *
4075     * @param string $fieldName nombre del campo
4076     * @param string $sql
4077     * @param mixed $value
4078     * @param array $atributes
4079     * @param string $formato
4080     * @param string $modo  el permiso 'Nada','R/O' o 'R/W'
4081     * @param bool $doSet
4082     * @return
4083     */
4084    function input_link_sql($fieldName,$sql=null,$value=null,$atributes=array(),$formato='link_one_select',&$modo=null,$doSet=true,$forzaEdit=false) {
4085    global $gAppRelate;
4086        if($modo==null)
4087            $modo=$this->puedo_campo($fieldName);
4088        if($modo=='Nada')
4089            return '';
4090
4091        if(!$forzaEdit && $modo=='R/O')
4092            return $this->display($fieldName,array(),$value,$modo);
4093        if($doSet) {
4094            $this->set_name_id_and_value($fieldName,$value, $atributes);
4095        }
4096
4097        if($sql==null) {
4098            $sql=$gAppRelate->sql_options_get($this->table,$fieldName, array_key_exists('link_item',$this->campos[$fieldName]) ? $this->campos[$fieldName]['link_item'] : '',$this,$value,true,false);
4099        }
4100        if(strpos($formato,'many')!==FALSE) {
4101            $this->atribute_setIfNotExists('multiple','multiple',$atributes);
4102            $this->atribute_setIfNotExists('size',$this->select_multiple_size,$atributes);
4103        }
4104        if(is_array($sql))
4105            return $this->input_link_array($fieldName,$sql,$value,$atributes,$formato,$modo,false,$forzaEdit);
4106        else
4107            return $this->input_link_array($fieldName,ia_sqlArray($sql,null),$value,$atributes,$formato,$modo,false,$forzaEdit);
4108    }
4109
4110    /**
4111     * iacase::input_link_array()
4112     *
4113     * @param string $fieldName nombre del campo
4114     * @param array $array valores posibles en el select
4115     * @param array $value valor actual
4116     * @param array $atributes
4117     * @param string $formato
4118     * @param string $modo el permiso 'Nada','R/O' o 'R/W'
4119     * @param bool $doSet
4120     * @return
4121     */
4122    function input_link_array($fieldName,$array=array(),$value=null,$atributes=array(),$formato='link_one_select',&$modo=null,$doSet=true,$forzaEdit=false) {
4123        if(empty($array))
4124            return '<select><option></option></select>';
4125
4126        if($modo==null)
4127            $modo=$this->puedo_campo($fieldName);
4128        if($modo=='Nada')
4129            return '';
4130        if(!$forzaEdit && $modo=='R/O')
4131            return $this->display($fieldName,array(),$value,$modo);
4132
4133        if($doSet) {
4134            $this->set_name_id_and_value($fieldName,$value, $atributes);
4135        }
4136        $required=array_key_exists('required',$atributes);
4137        $null=$this->campos[$fieldName]['Null'];
4138        // falta per_row
4139
4140        if( strpos($formato,'checkbox')!==false) {
4141
4142            if($required)
4143                $atributes['required']=null;
4144            if(array_key_exists('extra_option',$atributes))
4145                $atributes['extra_option']=null;
4146            $atributes['id']=null;
4147            $atributes['type']='checkbox';
4148            $this->atribute_remove('size',$atributes);
4149            $this->atribute_remove('multiple',$atributes);
4150            return $this->radio_checkbox($array,$value,$atributes);
4151
4152        }
4153        if( strpos($formato,'radio')!==false) {
4154            if(array_key_exists('extra_option',$atributes))
4155                $atributes['extra_option']=null;
4156            $atributes['id']=null;
4157            $atributes['type']='radio';
4158            return $this->radio_checkbox($array,$value,$atributes);
4159        }
4160
4161        if( !array_key_exists('extra_option',$atributes) && array_key_exists('extra_option',$this->campos[$fieldName]) )
4162            $atributes['extra_option']=$this->campos[$fieldName]['extra_option'];
4163        if(array_key_exists('extra_option',$atributes)) {
4164            $extra=$atributes['extra_option'];
4165            $atributes['extra_option']=null;
4166            if(is_array($extra)) {
4167                    foreach($extra as $k=>$v)
4168                        $extra_option='<option value="$k">$v</option>';      // falta selected
4169            } else
4170                $extra_option="<option value=''>$extra</option>";
4171            unset($atributes['extra_option']);
4172        }
4173        elseif( !array_key_exists('multiple',$atributes) && $null) {
4174            if(!array_key_exists('size',$atributes))
4175                $atributes['size']=1;
4176            $extra_option='<option value="">'.ia_htmlentities($this->array_val('seleccione',$this->campos[$fieldName],$this->seleccione)).'</option>';
4177        } else
4178            $extra_option='';
4179        unset($atributes['type']);
4180        if($required)
4181            unset($atributes['required']);
4182        if($this->h=='qbe')
4183            $extra_option="<option value=''></option>";
4184        if( array_key_exists('value',$atributes) )
4185            unset($atributes['value']);
4186
4187        //VCA Para Selectize
4188        $maxOptLen = 0;
4189        foreach($array as $k=>$v){
4190            if(is_array($v)){
4191                $i=0;
4192                foreach($v as $j=>$y){
4193                    $i++;
4194                    if($i==1)
4195                        continue;
4196                    $valLen = strlen($y);
4197                    if($i==2){
4198                        $maxOptLen = $valLen > $maxOptLen ? $valLen : $maxOptLen;
4199                        break;
4200                    }
4201                }
4202
4203            }
4204            else
4205                $maxOptLen = strlen($v);
4206        }
4207        $maxOptLen*=10;
4208        $maxOptLen = $maxOptLen < 130 ? 130 : $maxOptLen;
4209        if(array_key_exists('style',$atributes))
4210            $atributes['style'].= ' width:'.$maxOptLen.'px; ';
4211        else
4212            $atributes['style']= 'width:'.$maxOptLen.'px; ';
4213        /**
4214        if(array_key_exists('class',$atributes))
4215            $atributes['class'].= ' doSelectize ';
4216        else
4217            $atributes['class']= 'doSelectize';
4218        **/
4219
4220        //Para Selectize
4221        return '<select '.$this->atribute_toString($atributes).'>'.$extra_option.ia_Options_array($array,$value).'</select>';
4222    }
4223
4224    /**
4225     * iacase::radio_checkbox()
4226     *
4227     * @param mixed $array
4228     * @param string $selected
4229     * @param array $atributes
4230     * @param string $separator
4231     * @return
4232     */
4233    function radio_checkbox($array,$selected='',$atributes=array(),$separator='&nbsp;&nbsp;&nbsp;&nbsp;') {
4234        // falta per row
4235        $ret='';
4236        if( !empty( $array ) ) foreach($array as $key=>$data) {
4237           if(is_array($data)) {
4238               $k=$data['id'];
4239               $d=$data['label'];
4240               $class=" class='$data[class]";
4241           } else {
4242               $k=$key;
4243               $d=$data;
4244               $class='';
4245           }
4246           $k=ia_htmlentities($k);
4247            if(is_array($selected)) {
4248                $ret.="\r\n<input value='$k'$class".(in_array($k,$selected) ? " CHECKED='CHECKED' " : "").$this->atribute_toString($atributes)."/><span $class".ia_htmlentities($d)."</span>".$separator;
4249            } else {
4250                $ret.="\r\n<input value='$k'$class".(strcmp($selected,$k) ? "" : " CHECKED='CHECKED' ").$this->atribute_toString($atributes)."/><span $class".ia_htmlentities($d)."</span>".$separator;
4251            }
4252        }
4253        return $ret;
4254    }
4255
4256    function input_date($fieldName,$value=null,$atributes=array(),&$modo=null,$doSet=true) {
4257
4258        if($this->input_date_widget=='combos')
4259            return $this->input_date_combos($fieldName,$value,$atributes,$modo,$doSet);
4260        elseif($this->input_date_widget=='mobiscroll')
4261            return $this->input_date_mobiscroll($fieldName,$value,$atributes,$modo,$doSet);
4262       return $this->input_date_datepicker($fieldName,$value,$atributes,$modo,$doSet);
4263    }
4264
4265    /**
4266     * iacase::input_date_combos()
4267     *
4268     * @param string $fieldName nombre del campo
4269     * @param mixed $value
4270     * @param array $atributes
4271     * @param string $modo Nada, R/O, R/W
4272     * @param bool $doSet
4273     * @return
4274     */
4275    function input_date_combos($fieldName,$value=null,$atributes=array(),&$modo=null,$doSet=true) {
4276    global $gIAData;
4277
4278        // combos             var value = $("#year").val() + "-" + $("#month").val() + "-" + $("#day").val()
4279        if($modo==null)
4280            $modo=$this->puedo_campo($fieldName);
4281        if($modo=='Nada')
4282            return '';
4283        if($modo=='R/O')
4284            return $this->display($fieldName,array(),$value,$modo);
4285
4286        $max=array_val('max',$this->campos[$fieldName],'');
4287        $min=array_val('min',$this->campos[$fieldName],'');
4288
4289        $this->date_max_min($fieldName,$value,$atributes,$min,$max);
4290
4291        if($min!='') {
4292            $this->atribute_setIfNotExists('min',$min,$atributes);
4293            $yearMin=substr($min,0,4);
4294        } else {
4295            $yearMin=Date('Y')-50;
4296        }
4297        if($max!='') {
4298            $this->atribute_setIfNotExists('max',$max,$atributes);
4299            $yearMax=substr($min,0,4);
4300        } else {
4301            $yearMax=Date('Y')+1;
4302        }
4303
4304        $name=array_val('name',$atributes,$fieldName);
4305        $onchange=array_val('onchange',$atributes,'');
4306        if(empty($onchange))
4307            $atributes['onchange']="iacFecha('$name')";
4308        else
4309            $atributes['onchange'].=";iacFecha('$name')";
4310        if( !array_val('required',$this->campos[$fieldName]) )
4311            $extra_option='<option value="">'.ia_htmlentities($this->array_val('seleccione',$this->campos[$fieldName],$this->seleccione)).'</option>';
4312        else
4313            $extra_option='';
4314
4315        $atributes['id']=$atributes['name']='iacd_'.$name;
4316        $arr=array();
4317        for($i=1;$i<32;$i++)
4318            $arr[$i]=$i;
4319        $ret='<select '.$this->atribute_toString($atributes).'>'.$extra_option.ia_Options_KeyDisplay($arr,substr($value,-2)+0).'</select> ';
4320        $atributes['id']=$atributes['name']='iacm_'.$name;
4321        $ret.='<select '.$this->atribute_toString($atributes).'>'.$extra_option.ia_Options_KeyDisplay($gIAData['monthShort'],substr($value,5,2)+0).'</select> ';
4322
4323        $atributes['id']=$atributes['name']='iacy_'.$name;
4324        $ano=substr($value,0,4);
4325        if($this->h=='a' && empty($value) && $yearMax>$yearMin )
4326            $ano=($yearMax-$yearMin)/2;
4327
4328        $arr=array();
4329        for($i=$yearMin;$i<=$yearMax;$i++)
4330                $arr[$i]=$i;
4331        $ret.='<select '.$this->atribute_toString($atributes).'>'.$extra_option.ia_Options_KeyDisplay($arr,$ano).'</select>';
4332
4333        $atributes['id']=$atributes['name']=$name;
4334        $atributes['type']= 'hidden';
4335        $atributes['value']= $value;
4336        $atributes['onchange']='';
4337
4338        return $ret."<input ".$this->atribute_toString($atributes)." autocomplete='off'/>";
4339    }
4340
4341    /**
4342     * iacase::input_date_mobiscroll()
4343     *
4344     * @param string $fieldName nombre del campo
4345     * @param date $value
4346     * @param array $atributes
4347     * @param string $modo Nada, R/O, R/W
4348     * @param bool $doSet
4349     * @return
4350     */
4351    function input_date_mobiscroll($fieldName,$value=null,$atributes=array(),&$modo=null,$doSet=true) {
4352        // combos             var value = $("#year").val() + "-" + $("#month").val() + "-" + $("#day").val()
4353        if($modo==null)
4354            $modo=$this->puedo_campo($fieldName);
4355        if($modo=='Nada')
4356            return '';
4357        if($modo=='R/O')
4358            return $this->display($fieldName,array(),$value,$modo);
4359
4360        if($doSet) {
4361            $this->set_name_id_and_value($fieldName,$value, $atributes);
4362        }
4363        $this->atribute_setIfNotExists('maxlength','11',$atributes);
4364        $this->atribute_setIfNotExists('size','10',$atributes);
4365        $this->atribute_set('class',' mobilscroll_date ignore-val',$atributes,true);
4366
4367        $tmp=array('name'=>$atributes['name'],'id'=>$atributes['id']);
4368        $ret=$this->input_date_alt($fieldName,$value,$tmp,false);
4369
4370        $atributes['name'].='_viewdate';
4371        $atributes['id'].='_viewdate';
4372
4373        // falta ver si esta data-mobilscroll y ver si poner minDate y maxDate
4374        $max=$min='';
4375        $this->date_max_min($fieldName,$value,$atributes,$min,$max);
4376        //if($min!='')
4377        //    $this->atribute_setIfNotExists('min',$min,$atributes);
4378        //if($max!='')
4379        //    $this->atribute_setIfNotExists('max',$max,$atributes);
4380
4381        $atributes['value']=$value;
4382        //$atributes['class']='';
4383
4384        return $ret."<input ".$this->atribute_toString($atributes)." autocomplete='off'/>";
4385    }
4386
4387    /**
4388     * iacase::input_date_picker()
4389     *
4390     * @param string $fieldName nombre del campo
4391     * @param mixed $value
4392     * @param array $atributes
4393     * @param string $modo Nada, R/O, R/W
4394     * @param bool $doSet
4395     * @return
4396     */
4397    function input_date_datepicker($fieldName,$value=null,$atributes=array(),&$modo=null,$doSet=true) {
4398        // combos             var value = $("#year").val() + "-" + $("#month").val() + "-" + $("#day").val()
4399        if($modo==null)
4400            $modo=$this->puedo_campo($fieldName);
4401        if($modo=='Nada')
4402            return '';
4403        if($modo=='R/O')
4404            return $this->display($fieldName,array(),$value,$modo);
4405
4406        //$value = empty($value) ? '' : date('d-m-Y', strtotime($value));
4407
4408        if($doSet) {
4409            $this->set_name_id_and_value($fieldName,$value, $atributes);
4410        }
4411        $this->atribute_setIfNotExists('maxlength','11',$atributes);
4412        $this->atribute_setIfNotExists('size','10',$atributes);
4413        $this->atribute_set('class',' datepicker dpDate ignore-val',$atributes,true);
4414
4415        $tmp=array('name'=>$atributes['name'],'id'=>$atributes['id']);
4416        $ret=$this->input_date_alt($fieldName,$value,$tmp,false);
4417
4418        $atributes['name'].='_viewdate';
4419        $atributes['id'].='_viewdate';
4420
4421        $max=$min='';
4422        $this->date_max_min($fieldName,$value,$atributes,$min,$max);
4423        if($min!='')
4424            $this->atribute_setIfNotExists('min',$min,$atributes);
4425        if($max!='')
4426            $this->atribute_setIfNotExists('max',$max,$atributes);
4427
4428        $atributes['value']= $value;
4429        //$atributes['class']='';
4430
4431        return $ret."<input ".$this->atribute_toString($atributes)." autocomplete='off'/>";
4432    }
4433
4434    function input_datetime($fieldName,$value=null,$atributes=array(),&$modo=null,$doSet=true) {
4435        // combos             var value = $("#year").val() + "-" + $("#month").val() + "-" + $("#day").val()
4436        if($modo==null)
4437            $modo=$this->puedo_campo($fieldName);
4438        if($modo=='Nada')
4439            return '';
4440        if($modo=='R/O')
4441            return $this->display($fieldName,array(),$value,$modo);
4442
4443        if($doSet) {
4444            $this->set_name_id_and_value($fieldName,$value, $atributes);
4445        }
4446        $this->atribute_setIfNotExists('maxlength','11',$atributes);
4447        $this->atribute_setIfNotExists('size','16',$atributes);
4448        $this->atribute_set('class',' datetimepicker dpDate ignore-val',$atributes,true);
4449
4450        $tmp=array('name'=>$atributes['name'],'id'=>$atributes['id']);
4451        $ret=$this->input_date_alt($fieldName,$value,$tmp,false);
4452
4453        $atributes['name'].='_viewdate';
4454        $atributes['id'].='_viewdate';
4455
4456        $max=$min='';
4457        $this->date_max_min($fieldName,$value,$atributes,$min,$max);
4458        if($min!='')
4459            $this->atribute_setIfNotExists('min',$min,$atributes);
4460        if($max!='')
4461            $this->atribute_setIfNotExists('max',$max,$atributes);
4462
4463        $atributes['value']=$value;
4464        //$atributes['class']='';
4465
4466        return $ret."<input ".$this->atribute_toString($atributes)." autocomplete='off'/>";
4467    }
4468    /**
4469     * iacase::input_date_alt()
4470     *
4471     * @param string $fieldName nombre del campo
4472     * @param mixed $value
4473     * @param array $atributes
4474     * @param bool $doSet
4475     * @return
4476     */
4477    function input_date_alt($fieldName,$value=null,$atributes=array(),$doSet=true) {
4478        if($doSet) {
4479            $this->set_name_id_and_value($fieldName,$value, $atributes);
4480        }
4481        return "<input type='hidden' name='$atributes[name]' id='$atributes[id]' value='".ia_htmlentities($value)."' autocomplete='off' />";
4482    }
4483
4484    /**
4485     * iacase::date_max_min()
4486     *
4487     * @param string $fieldName nombre del campo
4488     * @param mixed $value
4489     * @param array $atributes
4490     * @param mixed $min
4491     * @param mixed $max
4492     * @return
4493     */
4494    function date_max_min($fieldName="",$value=null,$atributes=array(),&$min=0,&$max=0) {
4495        $incluye_sab=$this->campo_atribute_val($fieldName,'incluye_sab',$atributes,true,true);
4496        $incluye_dom=$this->campo_atribute_val($fieldName,'incluye_dom',$atributes,true,true);
4497        $forzaInicioAno=$this->campo_atribute_val($fieldName,'forzaInicioAno',$atributes,false,true);
4498
4499        $year_max=Date('Y-m-d');
4500        if($value!=null) {
4501            $year_ini=$year_value=$value;
4502        } else {
4503            $year_ini=$year_value='';
4504        }
4505
4506        $max=date_limit( $this->campo_atribute_val($fieldName,'max',$atributes,'',true),$incluye_dom,$incluye_sab,$forzaInicioAno);
4507        $min=date_limit( $this->campo_atribute_val($fieldName,'min',$atributes,'',true),$incluye_dom,$incluye_sab,$forzaInicioAno);
4508
4509        if(false && $min!='' && $year_value < $min )
4510            $min=$year_value;
4511        if( false && $max!='' && $year_value > $max )
4512            $max=$year_value;
4513    }
4514
4515    /**
4516     * iacase::input_anoMes()
4517     *
4518     * @param string $fieldName nombre del campo
4519     * @param mixed $value
4520     * @param array $atributes
4521     * @param string $modo Nada, R/O, R/W
4522     * @param bool $doSet
4523     * @return
4524     */
4525    function input_anoMes($fieldName,$value=null,$atributes=array(),&$modo=null,$doSet=true) {
4526    global $gIAData;
4527        if($modo==null)
4528            $modo=$this->puedo_campo($fieldName);
4529        if($modo=='Nada')
4530            return '';
4531        if($modo=='R/O')
4532            return $this->display($fieldName,array(),$value,$modo);
4533        if($doSet) {
4534            $this->set_name_id_and_value($fieldName,$value, $atributes);
4535        }
4536
4537        if( array_key_exists('incluye_sab',$atributes) ) {
4538            $incluye_sab= $atributes['incluye_sab'];
4539            unset($atributes['incluye_sab']);
4540        } else
4541            $incluye_sab=false;
4542        if( array_key_exists('incluye_dom',$atributes) ) {
4543            $incluye_dom= $atributes['incluye_dom'];
4544            unset($atributes['incluye_dom']);
4545        } else
4546            $incluye_dom=false;
4547
4548        $year_max=Date('Y');
4549        if($value!=null) {
4550            $year_ini=$year_value=substr($value,0,4);
4551        } else {
4552            $year_ini=$year_value='';
4553        }
4554
4555        $max=date_limit( $this->campo_atribute_val($fieldName,'max',$atributes,'',true),$incluye_dom,$incluye_sab);
4556        $min=date_limit( $this->campo_atribute_val($fieldName,'min',$atributes,'',true),$incluye_dom,$incluye_sab);
4557
4558        if($max!='' && $year_value > substr($max,0,4) )
4559            $max=$year_value;
4560        elseif($max=='')
4561            $max=Date('Y');
4562        else
4563            $max=substr($max,0,4);
4564
4565        if($min!='' && $year_value < substr($min,0,4) )
4566            $min=$max-10;
4567        if($min=='')
4568            $min=$max-10;
4569
4570//echo "<li>finale max=$max min=$min";
4571
4572
4573        $anos=array();
4574        for($i=$max;$i>=$min;--$i)
4575            $anos[$i]=$i;
4576
4577        $val=explode('/',$value);
4578        if( isset($val[0]) )
4579            $ano_value=$val[0];
4580        else
4581            $ano_value=Date('Y');
4582        if( !empty($ano_value) && !isset($anos[$ano_value]))
4583            $anos[$ano_value]=$ano_value;
4584
4585        if( isset($val[1]) )
4586            $mes_value=$val[1]+0;
4587        else
4588            $mes_value='';
4589
4590        $name=$atributes['name'];
4591        $id=$atributes['id'];
4592        $atributes['size']=1;
4593        $atributes['name']='iames_'.$name;
4594        $atributes['id']='iames_'.$id;
4595        $ret=$this->input_link_array($fieldName,$gIAData['monthLong'],$mes_value,$atributes,'link_one_select',$modo,false);
4596
4597        $atributes['name']='iaano_'.$name;
4598        $atributes['id']='iaano_'.$id;
4599        return $ret.' '.$this->input_link_array($fieldName,$anos,$ano_value,$atributes,'link_one_select',$modo,false);
4600
4601    }
4602
4603    /**
4604     * iacase::input_file()
4605     *
4606     * @param string $fieldName nombre del campo
4607     * @param mixed $value
4608     * @param array $atributes
4609     * @param string $modo Nada, R/O, R/W
4610     * @param bool $doSet
4611     * @return
4612     */
4613    function input_file($fieldName,$value=null,$atributes=array(),&$modo=null,$doSet=true) {
4614        if($modo==null)
4615            $modo=$this->puedo_campo($fieldName);
4616        if($modo=='Nada')
4617            return '';
4618        if($modo=='R/O')
4619            return $this->display($fieldName,array(),$value,$modo);
4620
4621        if($doSet) {
4622            $this->set_name_id_and_value($fieldName,$value, $atributes);
4623        }
4624
4625        $entries=$this->campo_key($fieldName,'file_max_entries',1);
4626        $this->atribute_set('class',"multi max-$entries",$atributes,true);
4627        $atributes['type']='file';
4628        $this->atribute_remove('maxlength',$atributes);
4629        $this->atribute_remove('required',$atributes);
4630        $this->atribute_remove('value',$atributes);
4631        if($entries>1)
4632            $atributes['name'].='[]';
4633        $this->atribute_set_from_campo($fieldName,'accept',$atributes);
4634        // falta current files en su caso
4635        return "<input ".$this->atribute_toString($atributes)." autocomplete='off' /><br />".$this->display_file_list($fieldName,array());
4636    }
4637
4638    /**
4639     * iacase::input_number()
4640     *
4641     * @param string $fieldName nombre del campo
4642     * @param mixed $value
4643     * @param array $atributes
4644     * @param string $modo Nada, R/O, R/W
4645     * @param bool $doSet
4646     * @return
4647     */
4648    function input_number($fieldName,$value=null,$atributes=array(),&$modo=null,$doSet=true) {
4649        if($modo==null)
4650            $modo=$this->puedo_campo($fieldName);
4651        if($modo=='Nada')
4652            return '';
4653
4654        if($modo=='R/O' && !array_key_exists('readonly',$this->campos[$fieldName]))
4655            return $this->display($fieldName,array(),$value,$modo);
4656
4657        if($doSet) {
4658            $this->set_name_id_and_value($fieldName,$value, $atributes);
4659        }
4660        $this->atribute_set('class',' auto ignore-val',$atributes,true);
4661        $this->atribute_setIfNotExists('data-autonumeric',$this->autonumeric_attribute($fieldName),$atributes);
4662        $this->atribute_set('type','text',$atributes);
4663        //falta size maxlength
4664        $dec=$this->campos[$fieldName]['decimales'];
4665
4666        $size=$this->campos[$fieldName]['enteros']+$dec+($dec>0 ? 1 : 0)+($this->array_val('unsigned',$this->campos[$fieldName],false) ? 1 : 0);
4667        $this->atribute_setIfNotExists('size',$size,$atributes);
4668        return "<input ".$this->atribute_toString($atributes)." autocomplete='off' />";
4669    }
4670
4671    /**
4672     * iacase::autonumeric_attribute()
4673     *
4674     * @param string $fieldName nombre del campo
4675     * @param mixed $enteros
4676     * @param mixed $decimales
4677     * @param mixed $AllowNegatives
4678     * @param mixed $min
4679     * @param mixed $max
4680     * @return
4681     */
4682    function autonumeric_attribute($fieldName,$enteros=null,$decimales=null,$AllowNegatives=null,$min=null,$max=null) {
4683        if(array_key_exists($fieldName,$this->campos)) {
4684            $enteros= $enteros==null ? $this->campo_key($fieldName,'enteros') : $enteros;
4685            $decimales= $decimales==null ? $this->campo_key($fieldName,'decimales') : $decimales;
4686            $min= $min==null ? $this->campo_key($fieldName,'min') : $min;
4687            $max= $max==null ? $this->campo_key($fieldName,'max') : $max;
4688            if($AllowNegatives==null) {
4689                //$tmp=$this->campo_key($fieldName,'unsigned');
4690                $tmp=$this->campo_key($fieldName,'AllowNegatives');
4691                if($tmp===null)
4692                    $AllowNegatives=false;
4693                elseif($tmp)
4694                    $AllowNegatives=true;
4695                else
4696                    $AllowNegatives=false;
4697            }
4698            if($AllowNegatives && $min===null)
4699                $min=0;
4700        }
4701
4702        if($enteros===null)
4703            $enteros=7;
4704        if($decimales===null)
4705            $decimales=2;
4706         if($max===null)
4707            $max=str_repeat('9',$enteros).($decimales>0 ? '.'.str_repeat('9',$decimales) : '' );
4708         if($min===null)
4709            if($AllowNegatives)
4710                $min='0'.($decimales>0 ? '.'.str_repeat('9',$decimales) : '' );
4711            else
4712                $min='-'.str_repeat('9',$enteros).($decimales>0 ? '.'.str_repeat('9',$decimales) : '' );
4713        // falta validator
4714        $miles=array_key_exists('aSep',$this->campos[$fieldName]) ?  $this->campos[$fieldName]['aSep'] : ',';
4715        //VCA
4716        $txtMin='';$txtMax='';
4717        if($AllowNegatives || $min === 0)
4718            $txtMin=",vMin:$min";
4719        $useMaxVal=false;
4720        if($useMaxVal || $max !== null)
4721            $txtMax=",vMax:$max";
4722
4723        return "{mNum:$enteros,mDec:$decimales,aSep:'$miles'$txtMin$txtMax".($this->campo_key($fieldName,'Null',false) || $this->h=='qbe' ? ",wEmpty:'empty'" : "" )."}";
4724        //return "{mNum:$enteros,mDec:$decimales,aSep:'$miles',vMin:$min,vMax:$max".($this->campo_key($fieldName,'Null',false) || $this->h=='qbe' ? ",wEmpty:'empty'" : "" )."}";
4725    }
4726
4727
4728
4729    /**
4730     * iacase::ori_field()
4731     *
4732     * @param string $fieldName nombre del campo
4733     * @param mixed $oriValue
4734     * @param mixed $name
4735     * @param string $modo Nada, R/O, R/W
4736     * @return
4737     */
4738    function ori_field($fieldName,$oriValue=null,$name=null,&$modo=null) {
4739
4740        if($modo==null)
4741            $modo=$this->puedo_campo($fieldName);
4742        if($modo=='Nada')
4743            return '';
4744        if($modo=='R/O')
4745            return ''; // $this->display($fieldName,array(),$value,$modo);
4746
4747        if($oriValue==null && array_key_exists($fieldName,$this->ori))
4748            $oriValue=$this->ori[$fieldName];
4749        if($oriValue==null)
4750            $oriValue='';
4751        if($name==null)
4752            $name=$fieldName;
4753        return "<input type='hidden' id='ori_$name' name='ori_$name' value='".ia_htmlentities($oriValue)."'/>";
4754    }
4755
4756    /**
4757     * iacase::set_name_id_and_value()
4758     *
4759     * @param string $fieldName nombre del campo
4760     * @param mixed $value
4761     * @param array $atributes
4762     * @return
4763     */
4764    function set_name_id_and_value($fieldName,&$value,&$atributes) {
4765        if(empty($value) && array_key_exists($fieldName,$this->values)) {
4766            $value=$atributes['value']=$this->values[$fieldName];
4767        }
4768        if($value!=null)
4769            $atributes['value']=$value;
4770        else
4771            $value='';
4772
4773        if($this->h=='e' || $this->h=='a' || $this->h=='s' || $this->h=='i') {
4774            if(array_key_exists($fieldName,$this->campos) && array_key_exists('input',$this->campos[$fieldName]) ) {
4775                if($this->campos[$fieldName]['input']) {
4776                        foreach($this->campos[$fieldName]['input'] as $k=>$d) {
4777                        if( $k === 'class')
4778                            $this->atribute_set($k,$d,$atributes, false, " ");
4779                        elseif($k=='style')
4780                            $this->atribute_set($k,$d,$atributes, true,';');
4781                        elseif( strcasecmp( substr($k,0,2),'on' )==0 )
4782                            $this->atribute_set($k,$d,$atributes,true,';');
4783                        else
4784                            $this->atribute_setIfNotExists($k,$d,$atributes);
4785                    }
4786                }
4787            }
4788        }
4789        if(array_key_exists('num',$atributes)) {
4790           $numC='['.$atributes['num'].']';
4791           $numId='_'.$atributes['num'];
4792           unset($atributes['num']);
4793        } else
4794            $numC=$numId='';
4795        if(!array_key_exists('name',$atributes))
4796            $atributes['name']=$fieldName.$numC;
4797        if(!array_key_exists('id',$atributes))
4798            $atributes['id']=$fieldName.$numId;
4799        foreach($this->campos[$fieldName]??[] as $k=>$v)
4800            if(substr($k,0,5)=='data-')
4801                $atributes[$k]=$v;
4802            elseif($k=='class' || $k=='style' ) {
4803                $atributes[$k]=$v;;
4804            }
4805    }
4806
4807////////////////////////////////////////////////////
4808// Atributos del element tag
4809////////////////////////////////////////////////////
4810    /**
4811     * iacase::atribute_set()
4812     *
4813     * @param mixed $atribute
4814     * @param mixed $value
4815     * @param mixed $arr
4816     * @param bool $append
4817     * @param string $separator
4818     * @return
4819     */
4820    function atribute_set($atribute,$value,&$arr,$append=false,$separator=' ') {
4821            if(!$append || !array_key_exists($atribute,$arr) )
4822                $arr[$atribute]=trim($value);
4823            elseif( strpos($arr[$atribute],$value)===FALSE )
4824                $arr[$atribute].=$separator.trim($value);
4825    }
4826
4827    /**
4828     * iacase::atribute_setIfNotExists()
4829     *
4830     * @param mixed $key
4831     * @param mixed $value
4832     * @param array $atributes
4833     * @return
4834     */
4835    public function atribute_setIfNotExists($key,$value,&$atributes) {
4836        if(!array_key_exists($key,$atributes)) {
4837            $atributes[$key]=$value;
4838        }
4839    }
4840
4841    /**
4842     * iacase::atribute_remove()
4843     *
4844     * @param mixed $atribute
4845     * @param array $atributes
4846     * @return
4847     */
4848    public function atribute_remove($atribute,&$atributes) {
4849        if(array_key_exists($atribute,$atributes))
4850            unset($atributes[$atribute]);
4851    }
4852
4853    /**
4854     * iacase::atribute_toString()
4855     *
4856     * @param array $atributes
4857     * @return
4858     */
4859    public function atribute_toString($atributes) {
4860        $a='';
4861        if(!empty($atributes)) foreach($atributes as $k=>$d)
4862            if(!is_array($d) && $d!=null)
4863                 $a.=' '.$k.='="'.trim(str_replace('"','\\"',$d)).'"';
4864                 //$a.=' '.$k.='="'.trim(ia_htmlentities($d)).'"';
4865        return $a;
4866    }
4867
4868    /**
4869     * iacase::campos_set_required()
4870     *
4871     * @param mixed $required
4872     * @param mixed $forFields
4873     * @return
4874     */
4875    function campos_set_required($required,$forFields=array()) {
4876        foreach($this->campos as $fieldName=>$f)
4877            if(empty($forFields) || array_key_exists($fieldName,$forFields) )
4878                if( $f['Type']!='enum' && $f['Type']!='set' )
4879                    $this->campos[$fieldName]['required']=$required;
4880    }
4881
4882    function campos_set_attribute($fieldNames,$atribute,$value) {
4883        if(is_array($fieldNames))
4884            foreach($fieldNames as $fieldName) {
4885                if(array_key_exists($fieldName,$this->campos))
4886                    $this->campos[$fieldName][$atribute]=$value;
4887            }
4888        else {
4889            if(array_key_exists($fieldNames,$this->campos))
4890                $this->campos[$fieldNames][$atribute]=$value;
4891        }
4892    }
4893
4894    function campos_push_attribute($fieldNames,$subArray,$atribute,$value) {
4895        if(is_array($fieldNames))
4896            foreach($fieldNames as $fieldName) {
4897                if(!array_key_exists($subArray,$this->campos[$fieldName]))
4898                    $this->campos[$fieldName][$subArray]=array();
4899                $this->campos[$fieldName][$subArray][$atribute]=$value;
4900            }
4901        else {
4902                if(!array_key_exists($subArray,$this->campos[$fieldNames]))
4903                    $this->campos[$fieldNames][$subArray]=array();
4904                $this->campos[$fieldNames][$subArray][$atribute]=$value;
4905        }
4906    }
4907
4908    function campos_append_attribute($fieldNames,$atribute,$value,$sep=' ') {
4909        if(is_array($fieldNames))
4910            foreach($fieldNames as $fieldName)
4911                if(array_key_exists('$atribute',$this->campos[$fieldName]))
4912                    $this->campos[$fieldName][$atribute].=$sep.$value;
4913                else
4914                    $this->campos[$fieldName][$atribute]=$value;
4915        else
4916                if(array_key_exists('$atribute',$this->campos[$fieldNames]))
4917                    $this->campos[$fieldNames][$atribute].=$sep.$value;
4918                else
4919                    $this->campos[$fieldNames][$atribute]=$value;
4920    }
4921
4922    /**
4923     * @param $fieldNames string o array de campos
4924     * @param $subArray sub atributo dentro del colmodel que queremos setear "BusquedaRapida"
4925     * @param $attribute nombre del atributo "type", "grupo", "extraf"
4926     * @param $value "ba_yes_no", "C O N T R O L"
4927     * @return void
4928     */
4929    function colmodel_set_attribute($fieldNames = "", $subArray = "BusquedaRapida", $attribute = "", $value = ""){
4930        if(is_array($fieldNames))
4931            foreach($fieldNames as $fieldName) {
4932
4933                if(empty($subArray)){
4934                    if(!array_key_exists($fieldName,$this->colModel_overRide))
4935                        $this->colModel_overRide[$fieldName] = [];
4936                    if(!array_key_exists($attribute,$this->colModel_overRide[$fieldName]) || !is_array($value))
4937                        $this->colModel_overRide[$fieldName][$attribute] = $value;
4938                    elseif(is_array($this->colModel_overRide[$fieldName][$attribute]) && is_array($value))
4939                        $this->colModel_overRide[$fieldName][$attribute] = array_merge($this->colModel_overRide[$fieldName][$attribute], $value);
4940                }
4941                else {
4942
4943                    if (!array_key_exists($fieldName, $this->colModel_overRide))
4944                        $this->colModel_overRide[$fieldName] = array($subArray => array());
4945
4946                    if (!array_key_exists($subArray, $this->colModel_overRide[$fieldName]))
4947                        $this->colModel_overRide[$fieldName][$subArray] = array();
4948
4949                    if (is_array($attribute))
4950                        $this->colModel_overRide[$fieldName][$subArray] = $attribute;
4951                    else
4952                        $this->colModel_overRide[$fieldName][$subArray][$attribute] = $value;
4953                }
4954            }
4955        else {
4956            if(empty($subArray)){
4957                if(!array_key_exists($attribute,$this->colModel_overRide[$fieldNames]) || !is_array($value))
4958                    $this->colModel_overRide[$fieldNames][$attribute] = $value;
4959                elseif(is_array($this->colModel_overRide[$fieldNames][$attribute]) && is_array($value))
4960                    $this->colModel_overRide[$fieldNames][$attribute] = array_merge($this->colModel_overRide[$fieldNames][$attribute], $value);
4961            }
4962            else {
4963
4964                if (!array_key_exists($subArray, $this->colModel_overRide[$fieldNames]))
4965                    $this->colModel_overRide[$fieldNames][$subArray] = array();
4966                $this->colModel_overRide[$fieldNames][$subArray][$attribute] = $value;
4967            }
4968        }
4969    }
4970////////////////////////////////////////////////////
4971// defults set
4972////////////////////////////////////////////////////
4973    /**
4974     * iacase::defaults_set()
4975     *
4976     * @param mixed $arr
4977     * @return
4978     */
4979    public function defaults_set(&$arr) {
4980        foreach($arr as $fieldName=>$d) {
4981           $arr[$fieldName]=$this->campo_key($fieldName,'Default','');
4982           if($arr[$fieldName]=='CURRENT_TIMESTAMP') {
4983                if($this->campo_key($fieldName,'Type','')=='date')
4984                    $arr[$fieldName]=Date('Y-m-d');
4985                else
4986                    $arr[$fieldName]=Date('Y-m-d H:i:s');
4987           }
4988        }
4989    }
4990////////////////////////////////////////////////////
4991// SELECT ONE RECORD
4992////////////////////////////////////////////////////
4993    /**
4994     * iacase::read_sql()
4995     *
4996     * @param string $id
4997     * @param string $h valor toca hacer normalmente param iah
4998     * @return
4999     */
5000    public function read_sql($id=null,$h=null, $table='') {
5001        // falta multiple primary key
5002        if($id==null)
5003            $id=param('id',param('iaid',param($this->table_info['pk_single_field'],$this->id)));
5004        if($h==null)
5005            $h=param('iah', $this->h);
5006        $virtuals = [];
5007        $virtualCols='';
5008        foreach($this->campos as $fieldName=>$f) if( array_key_exists('virtual_sql', $this->campos[$fieldName]) ) {
5009            $virtualCols .= ',' . $this->campos[$fieldName]['virtual_sql'];
5010            $virtuals[$fieldName] = $this->campos[$fieldName]['virtual_sql'];
5011        }
5012
5013        //echo "<li>SQL: SELECT /* iacase:read_sql */ $this->cols_read $virtualCols FROM $this->table WHERE ".$this->table_info['pk_single_field'].'='.strit($id);
5014
5015        if (empty($table)) {
5016            $table = (isset($this->table_real) && !empty($this->table_real))?$this->table_real: $this->table;
5017        }
5018        if(empty($this->pk_field))
5019            $this->pk_field = $table . "_id";
5020
5021        if(empty($this->table_info['pk_single_field']))
5022            $this->table_info['pk_single_field'] = $this->pk_field;
5023
5024        if($h==='a' || $h==='i') {
5025            return ia_singletonFull("SELECT /* iacase:read_sql */ $this->cols_read $virtualCols FROM $table WHERE ".$this->table_info['pk_single_field'].'='.strit('-1'),'');
5026        } elseif($h==='e' || $h==='s') {
5027            return ia_singleton("SELECT /* iacase:read_sql */ $this->cols_update $virtualCols FROM $table WHERE ".$this->table_info['pk_single_field'].'='.strit($id)  );
5028        }elseif($h==='r' || $h==='b'  || $h==='d') {
5029            // dd_("SELECT /* iacase:read_sql */ $this->cols_read $virtualCols FROM $table WHERE ".$this->table_info['pk_single_field'].'='.strit($id));
5030            return ia_singleton("SELECT /* iacase:read_sql */ $this->cols_read $virtualCols FROM $table WHERE ".$this->table_info['pk_single_field'].'='.strit($id)  );
5031        }
5032        return ia_singleton("SELECT /* iacase:read_sql */ $this->cols_read $virtualCols FROM $table WHERE ".$this->table_info['pk_single_field'].'='.strit($id)  );
5033    }
5034
5035////////////////////////////////////////////////////
5036// SELECT list
5037////////////////////////////////////////////////////
5038     /**
5039      * iacase::list_sql()
5040      *
5041      * @param string $cols
5042      * @return
5043      */
5044     public function list_sql($cols='') {
5045
5046     }
5047////////////////////////////////////////////////////
5048// INSERT STATEMENT
5049////////////////////////////////////////////////////
5050    /**
5051     * iacase::insert_sql()
5052     *
5053     * @param mixed $log
5054     * @param mixed $values
5055     * @return
5056     */
5057    public function insert_sql(&$log,$values=array()) {
5058        $excludeQuote=array();
5059        if(empty($values))
5060            $values=$this->values;
5061        if(empty($values))
5062            return '';
5063        $insArray=array();
5064        if($this->table_info['pk_single_type']=='uuid')
5065            $insArray[$this->pk_field]= $this->id;
5066        if($this->table_info['pk_single_type']=='iac_seq') {
5067            $insArray[$this->pk_field] = $this->id = $values[$this->pk_field];
5068        }
5069        foreach($values as $fieldName=>$v) if($this->cols_insert=='*' || strpos($this->cols_insert,$fieldName)!==FALSE ) {
5070            if( $fieldName!=$this->pk_field && $this->campo_key($fieldName,'modo')!='R/O'  && $this->campo_key($fieldName,'modo')!='Nada' ) {
5071                if($this->campo_key($fieldName,'Type')=='bit')
5072                    if($v)
5073                        $insArray[$fieldName]=1;
5074                    else
5075                        $insArray[$fieldName]=0;
5076                elseif( $this->campo_key($fieldName,'Null',false) &&  ($v==='' || $v===null)  )
5077                    $insArray[$fieldName]='NULL';
5078                elseif( $this->campo_key($fieldName,'numeric',false) &&  ($v==='' || $v===null)  )
5079                    $insArray[$fieldName]=0;
5080                elseif( $this->campo_key($fieldName,'datetime',false))
5081                    $insArray[$fieldName]=date('Y-m-d H:m:s', strtotime($v));
5082                elseif( $this->campo_key($fieldName,'date',false))
5083                    $insArray[$fieldName]=date('Y-m-d', strtotime($v));
5084                else
5085                    $insArray[$fieldName]=$v;
5086                if( strpos($v ?? "@##@",'iac_seq(')===0 )
5087                    $excludeQuote[]=$fieldName;
5088            }
5089            elseif( strpos($v,'iac_seq(')===0 )
5090                $excludeQuote[]=$fieldName;
5091            elseif(array_key_exists('Default',$this->campos[$fieldName]))
5092                $insArray[$fieldName]=$this->campos[$fieldName]['Default'];
5093
5094        }
5095        // sequences insert_value
5096        if(!empty($this->table_info['has_seq']))
5097            foreach($this->table_info['has_seq'] as $sF=>$seq)
5098                if( array_key_exists('insert_value',$seq) && !empty($seq['insert_value']) )
5099                    $insArray[$fieldName]=$seq['insert_value'];
5100
5101        if(!$this->insert_extra_values($insArray,$log))
5102            return '';
5103        if(empty($insArray))
5104            return '';
5105
5106        if(array_key_exists('alta_db',$this->campos))
5107            $insArray['alta_db']='NOW()';
5108        if(array_key_exists('ultimo_cambio',$this->campos))
5109            $insArray['ultimo_cambio']='NOW()';
5110        if(array_key_exists('alta_por',$this->campos))
5111            $insArray['alta_por']=$this->usuario;
5112        if(array_key_exists('ultimo_cambio_por',$this->campos))
5113            $insArray['ultimo_cambio_por']=$this->usuario;
5114        if(array_key_exists('iac_last_edit_ip',$this->campos))
5115            $insArray['iac_last_edit_ip']=ip_get();
5116
5117        return ia_insert($this->table,$insArray,$excludeQuote);
5118    }
5119
5120////////////////////////////////////////////////////
5121// UPDATE STATEMENT
5122////////////////////////////////////////////////////
5123    /**
5124     * iacase::update_sql()
5125     *
5126     * @param array $log
5127     * @param array $values
5128     * @param array $ori
5129     * @return
5130     */
5131    public function update_sql(&$log,$values=array(),$ori=array()) {
5132    global $gAppRelate;
5133        if(empty($values))
5134            $values=$this->values;
5135        if(empty($values))
5136            return '';
5137        if($this->conOri && empty($ori))
5138            $ori=$this->ori;
5139        $conOri=!empty($ori);
5140        $updArray=array();
5141        foreach($values as $fieldName=>$val) if($this->cols_update=='*' || strpos($this->cols_update,$fieldName)!==FALSE ) {
5142            if( $fieldName!=$this->pk_field && $this->campo_key($fieldName,'modo')!='R/O' && $this->campo_key($fieldName,'modo')!='Nada'
5143                && ( !$conOri || !array_key_exists($fieldName,$ori) || $ori[$fieldName]!=$val )  ) {
5144
5145                if( $this->campo_key($fieldName,'Type','')=='bit' ) {
5146                    if($val=='')
5147                        $val=0;
5148                    if( $conOri && array_key_exists($fieldName,$ori)  )
5149                        $oriVal= $ori[$fieldName] ? 1 : 0;
5150                    else
5151                        $oriVal=0;
5152                    if($oriVal!=$val) {
5153                        $updArray[$fieldName]=$val;
5154                    }
5155                } else {
5156                    if( $this->campo_key($fieldName,'Null',false) &&  ($val==='' || $val===null)  )
5157                        $updArray[$fieldName]='NULL';
5158                    elseif( $this->campo_key($fieldName,'numeric',false) &&  ($val==='' || $val===null)  )
5159                        $updArray[$fieldName]=0;
5160                    elseif( $this->campo_key($fieldName,'datetime',false))
5161                        $updArray[$fieldName]=date('Y-m-d H:m:s', strtotime($val));
5162                    elseif( $this->campo_key($fieldName,'date',false))
5163                        $updArray[$fieldName]=date('Y-m-d', strtotime($val));
5164                    elseif( $this->campo_key($fieldName,'Type','')=='set' ) {
5165                        if(is_array($val))
5166                            $updArray[$fieldName]=implode(',',$val);
5167                        else
5168                            $updArray[$fieldName]=$val;
5169                    } else
5170                       $updArray[$fieldName]=$val;
5171                    $oriVal=array_key_exists($fieldName,$ori) ? $ori[$fieldName] : '';
5172                }
5173
5174                //VCA OCT2019
5175                if($fieldName != 'remarks_wot')
5176                {
5177                    if ($this->campo_key($fieldName, 'formato') != 'fckeditor') {
5178                        if (array_key_exists($fieldName, $this->ori))
5179                            $era = " <i><strong>era</strong>: " . $this->display($fieldName, array(), $this->ori[$fieldName]) . "</i>";
5180                        elseif (array_key_exists($fieldName, $this->enDB))
5181                            $era = " <i><strong>era</strong>: " . $this->display($fieldName, array(), $this->enDB[$fieldName]) . "</i>";
5182                        else
5183                            $era = "";
5184                        $nada=null;
5185                        $this->log_field($fieldName, $this->display($fieldName, array(), $val, $nada, false) . $era, $log);
5186                    } else if(strcasecmp(
5187                        html_entity_decode($this->strim(strip_tags($this->nl2br($val)))),
5188                        html_entity_decode($this->strim(strip_tags($this->nl2br($oriVal))))
5189                    )){
5190                        //VCA NOV2020 25-11-2020
5191                        $era = " <i><strong>era</strong>: " . html_entity_decode($this->enDB[$fieldName] ?? "") . "</i>";
5192                        $this->log_field($fieldName, html_entity_decode($val) . PHP_EOL . $era, $log);
5193                    }
5194                }
5195
5196            } // if changed
5197        } // foreach
5198
5199        if(!$this->update_extra_sql($updArray,$log))
5200            return '';
5201
5202        if(empty($updArray))
5203            return '';
5204
5205        if(array_key_exists('ultimo_cambio',$this->campos))
5206            $updArray['ultimo_cambio']='NOW()';
5207        if(array_key_exists('ultimo_cambio_por',$this->campos))
5208            $updArray['ultimo_cambio_por']=$this->usuario;
5209        if(array_key_exists('iac_edits',$this->campos))
5210            $updArray['iac_edits']='iac_edits+1';
5211        if(array_key_exists('iac_last_edit_ip',$this->campos))
5212            $updArray['iac_last_edit_ip']=ip_get();
5213        // trigger workflows
5214        if($gAppRelate->has_workflow) {
5215            $this->changedMainTable=$updArray;
5216        }
5217
5218        return ia_update($this->table,$updArray,array($this->pk_field=>$this->id),array('iac_edits'));
5219    }
5220
5221    function strim($s) { return strim($s);}
5222    function nl2br($s) { return str_replace(array("\r\n", "\r", "\n"), "<br />", $s); }
5223    function br2nl($s)   { return preg_replace('/\<br(\s*)?\/?\>/i', "\n", $s); }
5224
5225////////////////////////////////////////////////////
5226// Files upload
5227////////////////////////////////////////////////////
5228
5229    /**
5230     * iacase::files_upload()
5231     *
5232     * @param string $id
5233     * @param array $sql
5234     * @param string $log
5235     * @return
5236     */
5237    function files_upload($id,&$sql,&$log) {
5238    global $gIApath;
5239
5240        $idField=$this->table_info['pk_single_field'];
5241        $del=param('ia_atdel');
5242
5243        if(!empty($del) && $del!='') {
5244            if(!is_array($del))
5245                $del=array($del);
5246            foreach($del as $d) {
5247                clearstatcache();
5248                $tmp=explode('|',$d);
5249                $fieldName=$tmp[0];
5250                if( isset($tmp[1])  && $this->files_valid($gIApath['DOCUMENT_ROOT'].substr($tmp[1],1),false)) {
5251                    if(array_key_exists(strtolower($fieldName),$this->campos)) { // && $this->campos[$fieldName]['formato']==s
5252                        @unlink($gIApath['DOCUMENT_ROOT'].substr($tmp[1],1));
5253                        if($this->campo_key(strtolower($fieldName),'file_max_entries',1)==1)
5254
5255
5256
5257
5258                            $sql[]="UPDATE /* iacase::files_upload */ $this->table SET $fieldName='' WHERE $idField=".strit($id)." LIMIT 1";
5259                        $this->log_field($fieldName,'Borra '.$fieldName.': '.basename($tmp[1]),$log);
5260                    } else {
5261                         $this->msg_err.="<li>No se borra ".ia_htmlentities($tmp[1])." error de transmision";
5262
5263                         //print_r($gIApath,true).print_r($tmp,true)."<pre>".$gIApath['FilePath'].substr($tmp[1],1);
5264                    }
5265                } else {
5266                    $this->msg_err.="<li>No se borra ".ia_htmlentities($tmp[1])." mal nombrado";
5267                }
5268            }
5269        }
5270
5271        if(empty($_FILES) )
5272            return;
5273
5274//ia_query("INSERT INTO dime(dime) VALUES(".strit($_FILES,true).")");
5275        $subir=array();
5276        foreach($_FILES as $fieldName=>$f) {
5277            if( array_key_exists('name',$f) ) {
5278                if(is_array($f['name']) ) {
5279                    if($f['name']) foreach($f['name'] as $i=>$d) {
5280                        $name=isset( $f['name'][$i] ) ?  $f['name'][$i] : '';
5281                        $type=isset( $f['type'][$i] ) ?  $f['type'][$i] : '';
5282                        $tmp_name=isset( $f['tmp_name'][$i] ) ?  $f['tmp_name'][$i] : '';
5283                        $error=isset( $f['error'][$i] ) ?  $f['error'][$i] : 9;
5284                        $size=isset( $f['size'][$i] ) ?  $f['size'][$i] : 0;
5285                        if($name!='')
5286                            $subir[$fieldName][] = array('name'=>$name ,'type'=>$type,'tmp_name'=>$tmp_name,'error'=>$error,'size'=>$size);
5287
5288                    }
5289                } else {
5290                        $name= array_key_exists('name',$f)  ?  $f['name'] : '';
5291                        $type= array_key_exists('type',$f)  ?  $f['type'] : '';
5292                        $tmp_name= array_key_exists('tmp_name',$f)  ?  $f['tmp_name'] : '';
5293                        $error= array_key_exists('error',$f)  ?  $f['error'] : 9;
5294                        $size= array_key_exists('size',$f)  ?  $f['size'] : 0;
5295                        if($name!='')
5296                            $subir[$fieldName][] = array('name'=>$name ,'type'=>$type,'tmp_name'=>$tmp_name,'error'=>$error,'size'=>$size);
5297                }
5298            }
5299        }
5300
5301
5302        foreach($subir as $fieldName=>$f) {
5303
5304            if( array_key_exists($fieldName,$this->campos) ) { // falta permiso en el campo
5305                $maxEntries=$this->campo_key($fieldName,'file_max_entries',1);
5306                $maxSize=$this->campo_key($fieldName,'file_max_size',2*1024*1024*1024);
5307                $paths=$this->files_deduce_dir($fieldName,$id);
5308
5309                if( false && !is_dir( substr($paths['fsPath'],0,-1) ) ) {
5310                    $this->msgError.="<li>".$fieldName.": invalid directory";
5311                } else {
5312                    if(!is_dir($paths['fsPath'])) {
5313                        $this->files_ensurePath($paths['fsPath']);
5314                    }
5315                    foreach($f as $a) {
5316                        if( $a['error'] ) {
5317                            $this->msg_err.='<li>Error al subir '.ia_htmlentities($a['name']).': '.uploadErrorStr($a['error']);
5318                        } elseif($maxSize>0 && $a['size']>$maxSize) {
5319                            $this->msg_err.='<li>'.ia_htmlentities($a['name']).' mide '.$a['size'].' m&aacute;ximo: '.$maxSize.' Bytes';
5320                        } elseif(!$this->files_valid($a['name'])) {
5321                           $this->msg_err.='<li>'.ia_htmlentities($a['name']).' nombre de archivo inv&aacute;lido! '.$fieldName;
5322                        } elseif(!$this->file_extension_valid($a['name'],$fieldName)) {
5323                            $this->msg_err.='<li>'.ia_htmlentities($a['name']).' no tiene extension valido para '.$fieldName;
5324                        } else {
5325                            $filename=filename_safe( $a['name'] ) ;
5326                            $uploaded_path=$paths['fsPath'].$filename;
5327                            $webPath=$paths['webPath'].$filename;
5328                            if( $maxEntries==1 ) {
5329                                //$this->table_info[''];
5330                                $tmp=ia_singleread("SELECT /* iacase:files_upload */ $fieldName FROM $this->table WHERE $idField=".strit($id)." LIMIT 1",'');
5331                                if($tmp!='' && is_file($gIApath['DOCUMENT_ROOT'].substr($tmp,1)) ) {
5332                                    @unlink($gIApath['DOCUMENT_ROOT'].substr($tmp,1));
5333                                }
5334                            }
5335                            if( move_uploaded_file($a['tmp_name'],$uploaded_path) ) {
5336                                $ok=true;
5337                            } elseif(copy($a['tmp_name'],$uploaded_path) ) {
5338                                $ok=true;
5339                            } else {
5340                                $ok=false;
5341                            }
5342                            if($ok) {
5343                                chmod($uploaded_path,0666);
5344                                if( $maxEntries==1 )
5345                                    $sql[]="UPDATE /* iacase:files_upload */ $this->table SET $fieldName=".strit($paths['webPath'].$filename)." WHERE $idField=".strit($id)." LIMIT 1";
5346                                else
5347                                    $sql[]="UPDATE /* iacase:files_upload */ $this->table SET $fieldName=".strit($paths['webPath'])." WHERE $idField=".strit($id)." LIMIT 1";
5348                                $this->log_field($fieldName,"sube archivo ".$a['name'],$log);
5349                            } else {
5350                                $this->msgError.="<li>$a[name]: Error de transmisi&oacute;n, no se pudo guardar";
5351                            }
5352                        }
5353                    }
5354                }
5355            }
5356        }
5357
5358    }
5359
5360    /**
5361     * iacase::file_extension_valid()
5362     *
5363     * @param mixed $file
5364     * @param string $fieldName nombre del campo
5365     * @return
5366     */
5367    public function file_extension_valid($file,$fieldName) {
5368        // falta
5369        return true;
5370    }
5371
5372    /**
5373     * iacase::files_valid()
5374     *
5375     * @param string $file
5376     * @return boolean true ok false no
5377     */
5378    public function files_valid($file,$forUpload=true) {
5379
5380        if($forUpload)
5381            $file=filename_safe($file);
5382
5383        if( empty($file) || $file=='.htaccess' || $file=='.' || $file=='..' || $file=='./' || $file=='../' || $file=='/'
5384            || $file==DIRECTORY_SEPARATOR || $file=='.'.DIRECTORY_SEPARATOR  || $file=='..'.DIRECTORY_SEPARATOR  )
5385            return false;
5386
5387        $invalid=array('../', '*','./',"\\",'?','...','//','~','$','"',"'","`","!","@","|","%","&","(",")","[","]","{","}",">","<"," ");
5388
5389        foreach($invalid as $d)
5390            if( !(strpos($file, $d )===FALSE) ) {
5391               return FALSE;
5392
5393            }
5394
5395        if($file=='.' || $file=='..' || $file=='*' || $file=='' || substr($file,0,1)=='.' )
5396            return FALSE;
5397        if($forUpload && ( substr($file,0,1)=='/' || substr($file,0,1)=='\\'  || substr($file,0,1)==DIRECTORY_SEPARATOR  ))
5398            return FALSE;
5399        if($forUpload)
5400        for($i=0;$i<strlen($file);++$i)
5401            if( ord($file[$i]) <=32 )
5402                return FALSE;
5403
5404        $ext = strtolower( filename_extension($file) );
5405        if($ext=='' || $ext=='php'  || $ext=='com'  || $ext=='exe'  || $ext=='bat'  || $ext=='dll'  )
5406            return FALSE;
5407        return TRUE;
5408    }
5409
5410    /**
5411     * iacase::files_deduce_dir()
5412     *
5413     * @param string $fieldName nombre del campo
5414     * @param string $id
5415     * @return
5416     */
5417    public function files_deduce_dir($fieldName,$id,$uploadDir=null) {
5418    global $gIApath;
5419            if(empty($uploadDir)) {
5420                if( !array_key_exists('FileUploadsDir',$gIApath) ) {
5421                    $uploadDir=$gIApath['WebPath']."uploads/";
5422                } else
5423                    $uploadDir=$gIApath['FileUploadsDir'];
5424                $uploadDir=str_replace("//","/",$uploadDir);
5425            }
5426
5427            //if( isset($gIApath['FileUploadsTable'][$this->table][$fieldName]) )
5428            //    $dirWeb=$gIApath['FileUploadsTable'][$this->table][$fieldName];
5429            //elseif( isset($gIApath['FileUploadsTable'][$this->table][0]) )
5430            //    $dirWeb=$gIApath['FileUploadsTable'][$this->table][0];
5431            //else
5432                $dirWeb=$uploadDir."$this->table/$id";
5433                $dirWeb=str_replace("//","/",$dirWeb);
5434            if(substr( $dirWeb,-1)!='/' )
5435                $dirWeb.='/';
5436            $dirWeb=str_replace("//","/",$dirWeb);
5437            if($id!='')
5438                $dirWeb.= "$fieldName/";
5439            $paths=array('webPath'=>$dirWeb,'fsPath'=>$gIApath['DOCUMENT_ROOT'].substr($dirWeb,1));
5440            return $paths;
5441    }
5442
5443    /**
5444     * iacase::files_ensuereDir()
5445     *
5446     * @param mixed $path
5447     * @return
5448     */
5449    public function files_ensurePath($path,$basePath='') {
5450    global $gIApath;
5451        if(empty($basePath))
5452            $basePath=$gIApath['DOCUMENT_ROOT'].substr($gIApath['WebPath'],1);
5453        if(substr($basePath,-1)=='/')
5454            $basePath=substr($basePath,0,-1);
5455        if(substr($path,-1)=='/')
5456            $path=substr($path,0,-1);
5457         clearstatcache(); //true,$path
5458        if(!is_dir($path))
5459            mkdir($path,0777,true);
5460
5461        $tmpPath=explode('/', str_replace( array($gIApath['DOCUMENT_ROOT'].substr($gIApath['WebPath'],1)),array('') ,$path ) );
5462        foreach($tmpPath as $dir) {
5463          $basePath.="/$dir";
5464           $this->files_ensuereDir($basePath);
5465        }
5466    }
5467    public function files_ensuereDir($path) {
5468        if( substr($path,-1)=='/' )
5469            $path=substr($path,0,-1);
5470        clearstatcache(); //true,$path
5471        if( is_dir($path) )
5472            return true;
5473        return mkdir($path,0777);
5474    }
5475////////////////////////////////////////////////////
5476// Auxiliares
5477////////////////////////////////////////////////////
5478
5479    /**
5480     * iacase::campo_key()
5481     *
5482     * @param string $fieldName nombre del campo
5483     * @param mixed $key
5484     * @param mixed $dflt
5485     * @return
5486     */
5487    public function campo_key($fieldName,$key,$dflt=null) {
5488        if(array_key_exists($fieldName,$this->campos) &&  array_key_exists($key,$this->campos[$fieldName]))
5489            return $this->campos[$fieldName][$key];
5490        return $dflt;
5491    }
5492
5493    /**
5494     * iacase::campo_atribute_val()
5495     *
5496     * @param string $fieldName nombre del campo
5497     * @param mixed $key
5498     * @param array $atributes
5499     * @param mixed $dflt
5500     * @param bool $unsetAttribute
5501     * @return
5502     */
5503    public function campo_atribute_val($fieldName,$key,&$atributes,$dflt=null,$unsetAttribute=false) {
5504/*
5505if(!is_array($atributes)) {
5506    echo "<li>$fieldName key=$key attr=".print_r($atributes,true)."</li>";
5507    echo "<pre>";
5508    debug_print_backtrace();
5509    echo "</pre><hr/>";
5510}
5511*/
5512        if(array_key_exists($key,$atributes)) {
5513            if($unsetAttribute) {
5514                $tmp=$atributes[$key];
5515                unset($atributes[$key]);
5516                return $tmp;
5517            }
5518            return $atributes[$key];
5519        }
5520        if(array_key_exists('data-'.$key,$atributes)) {
5521            if($unsetAttribute) {
5522                $tmp=$atributes['data-'.$key];
5523                unset($atributes['data-'.$key]);
5524                return $tmp;
5525            }
5526            return $atributes['data-'.$key];
5527        }
5528        $tmp=$this->campo_key($fieldName,$key,$dflt);
5529        if($tmp!=$dflt)
5530            return $tmp;
5531        return $this->campo_key($fieldName,'data-'.$key,$dflt);
5532    }
5533
5534    /**
5535     * iacase::atribute_set_from_campo()
5536     *
5537     * @param string $fieldName nombre del campo
5538     * @param mixed $key
5539     * @param array $atributes
5540     * @return
5541     */
5542    public function atribute_set_from_campo($fieldName,$key,&$atributes) {
5543        if(array_key_exists($key,$atributes))
5544            return;
5545        $tmp=$this->campo_key($fieldName,$key,'');
5546        if(!empty($tmp))
5547            $atributes[$key]=$tmp;
5548    }
5549
5550///////////////////////////////////////////////////////////////////
5551// child tables
5552///////////////////////////////////////////////////////////////////
5553    /**
5554     * iacase::child_tables_default()
5555     * Si la clase no define $this->childTables lo llena de $this->table_info que viene de appRelate.php
5556     * @return
5557     */
5558    function child_tables_default() {
5559
5560        if(!empty($this->childTables))
5561            return;
5562        if( $this->table_info['has_child'] && array_key_exists('links_from',$this->table_info))
5563            foreach($this->table_info['links_from'] as $childTable=>$childInfos) if( empty($this->childTablesUse) || in_array($childTable,$this->childTablesUse) ) {
5564
5565                foreach($childInfos as $k=>$d) {
5566                if(is_array($d) && array_key_exists('es', $d) && ($d['es']=='child' || $d['es']=='relate' || $d['es']=='key_value' || $d['es']=='key_value_select')) { //VCA aparecia error en es.
5567                    $d['childTableName']=$childTable;
5568
5569                    if( in_array( $childTable,$this->childHide) )
5570                        $d['hide']=true;
5571                    $this->childTables[]=$d;
5572                }
5573                }
5574            }
5575    }
5576
5577    /**
5578     * iacase::child_table_get()
5579     *
5580     * @param string $table
5581     * @param string $table_id
5582     * @param string $parent_id
5583     * @param string $parent_link
5584     * @param string $child_pk
5585     * @param string $orderBy
5586     * @param mixed $tag
5587     * @param mixed $child
5588     * @param mixed $class
5589     * @return
5590     */
5591    function child_table_get($table,&$table_id,&$parent_id,&$parent_link,&$child_pk,&$orderBy,&$tag,&$child,&$class) {
5592        if($table === 'producto_color_oculta' || $table === 'producto_color_nuevo')
5593            return false;
5594        global $gAppRelate;
5595        if(!array_key_exists($table,$gAppRelate->tables)) {
5596            return false;
5597
5598        } else {
5599            $child=$gAppRelate->tables[$table];
5600
5601            $child_pk = $child['pk_single_field'] ?? $table . '_id';
5602            $tmp='app_'.$table;
5603            try {
5604                $class = new $tmp();
5605            } catch(Throwable) {
5606                return false;
5607            }
5608            $class->asChild=true;
5609            $fields=$class->campos;
5610        }
5611        if($parent_id==null)
5612            $parent_id = $this->id;
5613        if($parent_id==null)
5614            $parent_id ='';
5615
5616        if(empty($parent_link)) {
5617            if(array_key_exists('links_to',$child) && array_key_exists($this->table,$child['links_to']) ) {
5618                foreach($child['links_to'][$this->table] as $campo=>$d)
5619                    break;
5620                $parent_link=$child['links_to'][$this->table][$campo]['to_field']; // era 'campo'
5621                $child['links_este']=$child['links_to'][$this->table][$campo];
5622
5623                $child['from_este']=array_key_exists($d['to_field'],$gAppRelate->tables[$this->table]['links_from'][$table]) ? $gAppRelate->tables[$this->table]['links_from'][$table][$d['to_field']] : false;
5624                //$child['links_este']['parent_field']=$child['links_to'][$this->table][$campo]['to_field']; // era sin comentar era campo
5625                //echo "<div>table=$table eta=$this->table campo=$campo parent_link=$parent_link parent_id=$parent_id child_ok=$child_pk</div><pre>".print_r( $child['links_to'],true )."</pre>";
5626            } else
5627                echo "<li>$table not a child for $this->table!</li>";
5628        }
5629        if(empty($tag)) {
5630            foreach($fields as $fieldName=>$v)
5631                if($fieldName!=$parent_link && $fieldName!=$child_pk)
5632                    $tag[$fieldName]=array();
5633        }
5634        foreach($tag as $fieldName=>$t) {
5635            if(!array_key_exists('modo',$t) && array_key_exists($fieldName,$fields) )
5636                $tag[$fieldName]['modo']=$fields[$fieldName]['modo'];
5637        }
5638        if($table_id==null)
5639            $table_id='chldtbl_'.$table;
5640        if($orderBy=='')
5641            $orderBy=" ORDER BY ".$child['label_field'];
5642
5643       if(  $parent_link==null || empty($tag) || empty($child) || empty($class)  )
5644        return false;
5645       return true;
5646    }
5647
5648    /**
5649     * iacase::child_table_save_all()
5650     *
5651     * @param array $sql
5652     * @param array $log
5653     * @return
5654     */
5655    function child_table_save_all(&$sql,&$log) {
5656        if(!$this->saveChilds || !$this->table_info['has_child'])
5657            return;
5658        $this->child_tables_default();
5659        foreach($this->childTables as $childDef) {
5660            if(!array_key_exists('hide',$childDef) || !$childDef['hide'] )
5661                $this->child_table_save($childDef['childTableName'],$sql,$log);
5662        }
5663    }
5664
5665    /**
5666     * iacase::child_table_save()
5667     *
5668     * @param string $table
5669     * @param array $sql
5670     * @param array $log
5671     * @param number $table_id
5672     * @param string $parent_id
5673     * @param array $parent_link
5674     * @param string $named
5675     * @return
5676     */
5677    function child_table_save($table,&$sql,&$log,$table_id=null,$parent_id=null,$parent_link=null,$named=null) {
5678        $class=null;
5679        if(!$this->child_table_get($table,$table_id,$parent_id,$parent_link,$child_pk,$orderBy,$tag,$child,$class) )
5680            return;
5681        if($named==null)
5682            $named=$table;
5683        $link_este=$child['links_este'];
5684
5685//echo "<hr><li>table=$table, plink=$parent_link, chpk=$child_pk <pre>".print_r($link_este,true)."</li>";
5686        if($link_este['formato']=='link_many_select' && array_key_exists('options',$link_este)) {
5687            $vals=param($table);
5688            $catField=$link_este['catField'];
5689            if(is_array($vals)) {
5690                $values='';
5691                $dels='';
5692                if(!empty($vals)) foreach($vals as $v) {
5693                    $dels.=stritc($v);
5694                    $values.=',('.stritc($parent_id).strit($v).')';
5695                }
5696                if(!empty($values)) {
5697                    $sql[]="INSERT /*iacase:child_table_save*/ INTO $table($parent_link,$catField) VALUES".substr($values,1)." ON DUPLICATE KEY UPDATE $catField=VALUES($catField)";
5698                    $sql[]="DELETE FROM $table WHERE $parent_link=".strit($parent_id)." AND $catField NOT IN (".substr($dels,0,-1).')';
5699                } else
5700                    $sql[]="DELETE FROM $table WHERE $parent_link=".strit($parent_id);
5701            } elseif(!empty($vals)) {
5702                $sql[]="INSERT /*iacase:child_table_save*/ INTO $table($parent_link,$catField) VALUES(".stritc($parent_id).strit($vals).") ON DUPLICATE KEY UPDATE $catField=VALUES($catField)";
5703                $sql[]="DELETE /*iacase:child_table_save*/ FROM $table WHERE $parent_link=".strit($parent_id)." AND $catField <> ".strit($vals);
5704            } else
5705                $sql[]="DELETE /*iacase:child_table_save*/ FROM $table WHERE $parent_link=".strit($parent_id);
5706
5707        }
5708        elseif($link_este['formato']=='key_value_select') {
5709            $key=$link_este['key_value_select'][0];
5710            $key_field=$key['relateid'];
5711            $value=$link_este['key_value_select'][1];
5712            $value_field=$value['relateid'];
5713            $key_values=param($key_field);
5714            $value_values=param($value_field);
5715            $dels='';
5716            $ins='';
5717            if(!empty($key_values)) foreach($key_values as $k=>$v) {
5718                $tmp=array_key_exists($k,$value_values) ? $value_values[$k] : 0;
5719                if(empty($tmp))
5720                    $dels.=stritc($v);
5721                else
5722                    $ins.='('.stritc($this->id).stritc($v).strit($tmp).'),';
5723            }
5724            if(!empty($dels))
5725                $sql[]="DELETE /*iacase:child_table_save*/ FROM $table WHERE $this->pk_field=".strit($this->id)." AND $key_field IN(".substr($dels,0,-1).')';
5726            if(!empty($ins))
5727                $sql[]="INSERT /*iacase:child_table_save*/ INTO $table($this->pk_field,$key_field,$value_field) VALUES".substr($ins,0,-1)." ON DUPLICATE KEY UPDATE $value_field=VALUES($value_field)";
5728        } elseif($link_este['formato']=='addanother') {
5729            $childPK=$child['pk_single_field'] ?? '';
5730            $got="iacadd_$table";
5731            $arr=param($got);
5732            $ori=param("ori_$got");
5733            $ids='';
5734            if( !empty($arr) ) foreach($arr as $tk=>$tv)
5735                if( array_val($childPK,$tv))
5736                    $ids.=stritc($tv[$childPK]);
5737            $ids=substr($ids,0,-1);
5738            $ori_ids=param($got.'_ids');
5739            if(!empty($ori_ids) && $ids!=$ori_ids )
5740                $sql[]="DELETE /*iacase:child_table_save*/ FROM $table WHERE $link_este[this_field]=".strit($this->id)." AND $childPK NOT IN($ids)";
5741
5742            if( !empty($arr) ) {
5743                foreach($arr as $k=>$v) {
5744                    $hay=false;
5745                    $queryArr=array();
5746                    $pkValue='';
5747                    foreach($v as $fieldName=>$f) {
5748                        if($fieldName==$childPK) {
5749                            $pkValue=$f;
5750                        } elseif(!empty($f) && $ori[$k][$fieldName]!=$f) {
5751                            $hay=true;
5752                            $queryArr[$fieldName]=$f;
5753                        } elseif($ori[$k][$fieldName]!=$f) {
5754                            $hay=true;
5755                            if( array_val('Null',$class->campos[$fieldName],false) )
5756                                $queryArr[$fieldName]=null;
5757                            else {
5758                                $queryArr[$fieldName]=array_val('Default',$class->campos[$fieldName],'');
5759                            }
5760                        }
5761
5762                    }
5763                    if($hay) {
5764                        if(empty($v[$childPK])) {
5765                            $queryArr[$link_este['this_field']]=$this->id;
5766                            $sql[]=ia_insert($table,$queryArr);
5767                        } else {
5768                            $sql[]=ia_update($table,$queryArr,"$childPK=".strit($pkValue));
5769                        }
5770                    }
5771                }
5772            }
5773
5774        }
5775        return;
5776//echo "<hr><li>table=$table parent_link=<pre>".print_r($link_este,true)."<p>REQ=".print_r($_REQUEST[$table],true)."</pre></li>";
5777        $fieldsDo='';$fieldsDoArr=array();
5778        foreach($class->campos as $tk=>$t ) {
5779                if($tk!=$child_pk && $tk!=$parent_link && $tk!='alta_db' && $tk!='alta_por' && $tk!='ultimo_cambio' && $tk!='ultimo_cambio_por' ) {
5780                    $fieldsDo.=",$tk";
5781                    $fieldsDoArr[]=$tk;
5782                }
5783        }
5784        $got=param($named);
5785       $ori=param("ori_$named");
5786       if(empty($ori))
5787        $ori=array();
5788
5789        $llego=array();
5790        $irows=0;
5791        if(!empty($got)) foreach($got as $kg=>$g) {
5792            $irows++;
5793
5794            if( !array_key_exists($child_pk,$g) )
5795                $g[$child_pk]='';
5796
5797            if( array_key_exists($child_pk,$g) )  {
5798                if(!empty($g[$child_pk]))
5799                    $llego[$g[$child_pk]]=$g[$child_pk];
5800                $class->values=array();
5801                $class->ori=array();
5802                $class->ori[$parent_link]=$class->values[$parent_link]=$this->id;
5803                $class->ori[$child_pk]=$class->values[$child_pk]=$g[$child_pk];
5804                $dome=false;
5805
5806                foreach($fieldsDoArr as $fieldName) {
5807                    $class->values[$fieldName]= array_key_exists($fieldName,$g)    ? $g[$fieldName] : '';
5808                    $class->ori[$fieldName]=array_key_exists($kg,$ori) && array_key_exists($fieldName,$ori[$kg]) ? $ori[$kg][$fieldName] : '';
5809                    if($fieldName!=$parent_link && $fieldName!=$child_pk && !empty($class->values[$fieldName]) )
5810                        $dome=true;
5811                    elseif($fieldName!=$parent_link && $fieldName!=$child_pk && empty($class->values[$fieldName]) && !empty($g[$child_pk]) )
5812                        $dome=true;
5813                }
5814
5815                if($dome) { // do save
5816                    $class->enDB=$class->ori;
5817                    $tmp='';
5818                    if( empty($g[$child_pk]) )  {
5819                        $sql[]=$class->insert_sql($tmp);
5820                        $log.="<li>Agrega ".$class->label_record_summary();
5821                    }  else {
5822                        $sql[]=$class->update_sql($tmp);
5823                        $log.="<li>Edita ".$class->label_record_summary();
5824                    }
5825                }
5826            }
5827        }
5828        // delete rows
5829        $namedids=param($named.'_ids');
5830        if($namedids!='') {
5831            $ids_sent=explode(',',$namedids);
5832            if(!empty($ids_sent)) foreach($ids_sent as $sent) if($sent!='' && !array_key_exists($sent,$llego)  )  {
5833              $sql[]="DELETE FROM $table WHERE $child_pk=".strit($sent)." AND $parent_link=".strit($this->id) ;
5834              $log.="<li>Elimina ".$class->label;
5835            }
5836        }
5837    }
5838
5839    /**
5840     * array_val()
5841     *
5842     * @param string $key
5843     * @param array $array
5844     * @param mixed $default
5845     * @return mixed valor de $key en el array o $default de no existir
5846     */
5847    function array_val($key,$array,$default=false) {
5848        if(array_key_exists($key,$array))
5849            return $array[$key];
5850        return $default;
5851    }
5852
5853    function to_label($label) { if($label==$this->pk_field) return to_label($label).' Id'; return to_label($label); }
5854
5855    function child_table_key_value_select($table,$orderBy,$link_este,$child,$class) {
5856    global $gAppRelate;
5857        $ret='';
5858        $ret.= "<label class='lbl'>".$this->to_label($table)."</label>";
5859        if($this->h=='e' || $this->h=='a') {
5860            $key=$link_este['key_value_select'][0];
5861            $key_field=$key['relateid'];
5862            $keys=ia_sqlArray($gAppRelate->sql_options_get($key['table'],$key_field, $key['table_pk'] ));
5863
5864            $value=$link_este['key_value_select'][1];
5865            $value_field=$value['relateid'];
5866            $values=ia_sqlArray($gAppRelate->sql_options_get($value['table'],$value['relateid'], $value['table_pk'] ));
5867            $selected=ia_sqlArray("SELECT /*child_table_key_value_select*/ $table"."_id,$key_field$value_field FROM $table WHERE $this->pk_field=".strit($this->id),$table.'_id');
5868            $ret.="<table>";
5869            $i=0;
5870            if($keys) foreach($keys as $k=>$v) {
5871                $key_selected=$value_selected='';
5872                if($selected)
5873                    foreach($selected as $s)
5874                        if($s[$key_field]==$k) {
5875                            $key_selected=$k;
5876                            $value_selected=$s[$value_field];
5877                        }
5878
5879                $ret.=($i%2 ? '' : '<tr>')."<td><input type=hidden name='$key_field"."[".(++$i)."]' value='$k'/>".ia_htmlentities($v['label'])."<td><select name='$value_field"."[$i]'>".ia_OptionsSetData($values,$value_selected,array(0=>'No Aplica'))."</select><br />&nbsp;";
5880            }
5881            $ret.="</table>";
5882        } else {
5883            $select='';
5884            $from='';
5885            $iDisplay=0;
5886            foreach($link_este['key_value_select'] as $cual) {
5887                $select.="$cual[table].$cual[label]";
5888                $from.=" LEFT JOIN $cual[table] ON $cual[table].$cual[table_pk]=$table.$cual[relateid]";
5889                $iDisplay++;
5890            }
5891            $relationPK=$table.'_id';
5892            $vals = ia_sqlArray("SELECT $table.$relationPK $select FROM $table $from WHERE $this->pk_field=".strit($this->id) ,0,MYSQL_NUM);
5893
5894            if(!empty($vals)) {
5895                $ret.='<table>';
5896                $j=0;
5897                foreach($vals as $d) {
5898                    $ret.=$j++%2 ? '' : '<tr>';
5899                    for($i=1;$i<=$iDisplay;$i++)
5900                        $ret.="<td>". ia_htmlentities($d[$i]);
5901                }
5902                $ret.='</table>';
5903            }
5904        }
5905        return $ret;
5906    }
5907
5908    function child_table_multiselect($table,$orderBy,$link_este,$child,$class) {
5909    global $gAppRelate;
5910        $ret='';
5911        //echo "<pre>table=$table link=".print_r($link_este,true)."<p>table trae ".print_r($gAppRelate->tables[$table],true);
5912        $ret.= "<label class='lbl'>".$this->to_label($table)."</label>";
5913        if($this->h=='r' || $this->h=='b') {
5914            $tmp=ia_sqlArray( str_replace('%id%',strit($this->id),$link_este['read']) );
5915            if(!empty($tmp)) {
5916                $ret.=PHP_EOL."<ul>";
5917                foreach($tmp as $k=>$dat) {
5918                    $ret.="<li>";
5919                    foreach($dat as $n=>$v) {
5920                        if($n=='icono')
5921                            $ret.=" <img src='$v' />";
5922                        elseif( $n!='id' && substr($n,-3)!='_id')
5923                            $ret.=ia_htmlentities($v);
5924                    }
5925                }
5926                $ret.=PHP_EOL."</ul>";
5927            }
5928        } else {
5929            $tmp=ia_sqlArray( str_replace('%id%',strit($this->id),$link_este['options']) );
5930            if(!empty($tmp)) {
5931                $ret.=PHP_EOL."<div style='margin:auto;'><select name='$table"."[]' id='$table' multiple=multiple class='multiselect' size=12>";
5932                foreach($tmp as $k=>$dat) {
5933                  $ret.="<option value='$k'".(array_key_exists('value',$dat) && $dat['value'] ? ' SELECTED=SELECTED' : '' ).">".ia_htmlentities($dat['label'])."</option>";
5934                }
5935                $ret.=PHP_EOL."</select></div>";
5936            }
5937        }
5938        return $ret;
5939    }
5940
5941    /**
5942     * iacase::child_table_jqgrid()
5943     *
5944     * @param string $table
5945     * @param string $orderBy
5946     * @param string|null $gridId
5947     * @param mixed $forzaUpdate
5948     * @param mixed $forzaDelete
5949     * @param mixed $forzaAdd
5950     * @param mixed $editURL
5951     * @param mixed $extraButtonActions
5952     * @return string|void
5953     */
5954    function child_table_jqgrid($table,$orderBy,$gridId=null,$forzaUpdate=null,$forzaDelete=null,$forzaAdd=null,$editURL=null,$extraButtonActions=null) {
5955        $table_id=$parent_id=$parent_link=$child_pk=$orderBy=$tag=$child=$class=null;
5956        if(!$this->child_table_get($table,$table_id,$parent_id,$parent_link,$child_pk,$orderBy,$tag,$child,$class) )
5957            return "$table not found!";
5958        $link_este=$child['links_este'];
5959        $linkField=$link_este['this_field'];
5960
5961        $class->asChild=true;
5962        /*
5963        if( isset($class->label_child))
5964            $class->label = $class->label;*/
5965        if(property_exists($this,'child_label_prefixme') && $this->child_label_prefixme === true) {
5966            $class->label = $this->label_record()." ".$class->label;
5967        }
5968
5969
5970        if(array_key_exists('display_method_parent',$link_este) && !empty($link_este['display_method_parent'])) {
5971            echo $this->$link_este['display_method_parent']($this->table, $table,$link_este,$child);
5972            return;
5973        }
5974        if(array_key_exists('display_method_child',$link_este) && !empty($link_este['display_method_child'])) {
5975            echo $class->$link_este['display_method_child']($this->table, $table,$link_este,$child);
5976            return;
5977        }
5978
5979        if( stripos( $link_este['formato'], 'link_many')!==FALSE ) {
5980            echo $this->child_table_multiselect($table,$orderBy,$link_este,$child,$class);
5981            return;
5982        }
5983
5984        if($link_este['formato']=='key_value_select') {
5985            echo $this->child_table_key_value_select($table,$orderBy,$link_este,$child,$class);
5986            return;
5987        }
5988
5989        $class->modo=$this->array_val('modo',$link_este, $class->modo);
5990
5991        $doActions=false;
5992
5993        $h=$this->h;
5994        $class->h=$h;
5995        $view=$class->may_read();
5996        // permisos y actions
5997        $editable=($h=='a' || $h=='e' || $h=='s' || $h=='i');
5998        $permiso=$this->array_val('permiso',$link_este, 'R/W');
5999        if($permiso=='Nada')
6000            return;
6001        if($permiso=='R/O')
6002            $editable=false;
6003        if(!$class->may_list())
6004            return '';
6005        $actions=array();
6006        if($editable) {
6007            $update=$class->may_update();
6008            $delete=$class->may_delete();
6009            $add=$class->may_insert();
6010            if($forzaAdd!==null && $add)
6011                $add=$forzaAdd;
6012
6013            if($forzaUpdate===false)
6014                $update=$forzaUpdate;
6015
6016            if(($this->deleteChilds === true || $forzaDelete!==null) && $delete)
6017                $delete=$forzaDelete;
6018            elseif( is_array($child['from_este']) && array_key_exists('restrict_delete',$child['from_este']) && $child['from_este']['restrict_delete'] )
6019                $delete=false;
6020
6021            $gridAdd=$add ? $this->array_val('gridAdd',$link_este,$add) : false;
6022            $gridDelete=$delete ? $this->array_val('gridDelete',$link_este,$delete) : false;
6023            $gridUpdate=$update ? $this->array_val('gridUpdate',$link_este,$update) : false;
6024            $gridView=$view ? $this->array_val('gridView',$link_este,$view) : false;
6025
6026            if($this->editChildsSetRO) {
6027                $gridAdd=$gridDelete=$gridUpdate=$gridView=$doActions=$update=$add=$delete=$doActions=false;
6028            }
6029
6030            if($update && $this->array_val('gridActions',$link_este,true) ) {
6031                $doActions=true;
6032                // falta rutina hacedora de actions!
6033                    $actions=array( 'externEdit'=>$update,'externView'=>false
6034                        ,'formatoptions'=> array(
6035                            'editbutton'=>false,
6036                            'editformbutton'=>false,
6037                            'delbutton'=>false
6038                        )
6039                    );
6040
6041                $actions=array( 'externEdit'=>true
6042                    ,'externView'=>false
6043                    ,'externDel'=>false
6044                    ,'extern'=>array(
6045                        'edit'=>  $update ?  array('dialog'=>true) : null
6046                        )
6047                    ,'formatoptions'=> array('editbutton'=>false,'editformbutton'=>false,'delbutton'=>false)
6048                );
6049
6050            }
6051        } else {
6052            $update=$delete=$add=false;
6053            $gridAdd=$gridDelete=$gridUpdate=false;
6054        }
6055//$gridAdd=true;
6056
6057        $doActions=$this->array_val('gridActions ',$link_este,$doActions);
6058        if($doActions)
6059            $actions=$class->child_jqgrid_actions($table.'.php',$class,$doActions,$gridView,$gridUpdate,$gridAdd,$gridDelete,$extraButtonActions);
6060        else
6061            $actions=array();
6062
6063        if(!empty($extraButtonActions)) foreach($extraButtonActions as $b) {
6064             $actions['extern'][]=$b;
6065        }
6066
6067        // list records
6068        $where="$linkField=".strit($this->id);
6069        if(array_key_exists('where',$link_este))
6070            $where.=' AND '.$link_este['where'];
6071
6072        if(property_exists($this, 'child_jqGrid_extrawhere') && !empty($this->child_jqGrid_extrawhere))
6073            $where.=' AND '.$this->child_jqGrid_extrawhere;
6074
6075        // extra params
6076            $extraParams=array($parent_link=>$this->id);
6077
6078        // grid id
6079            $gridId= empty($gridId) ? "ac$table" : $gridId;
6080
6081        // define grid
6082        if($h=='e' || $h=='i')
6083            $title=$this->array_val('title_edit',$link_este,  $this->array_val('title',$link_este,'' ) );
6084        else
6085            $title=$this->array_val('title_view',$link_este,  $this->array_val('title',$link_este,'' ) );
6086
6087            if(!empty($title))
6088                $title = $class->label_list().$title;
6089            //        $this->child_jqGridSaveState=false; // se esta desfasando en true!
6090
6091            $grid=new iaJQGrid_base($gridId, $title,$editable,$this->child_jqGridSaveState,true);
6092            if(!empty($editURL))
6093                 $grid->set_option('editurl',$editURL);
6094            $grid->saveStateClear=true;
6095            $grid->postData_set( array($parent_link=>$this->id) );
6096            $grid->set_option('height',$this->child_jqGrid_height);
6097            $grid->set_option('width', $this->array_val('gridWidth',$link_este, $this->child_jqGrid_width ));
6098            $grid->set_option('hidegrid',false);
6099            $grid->set_option('width',"\$($grid->gridVar).parent().width()-25");
6100            if(!empty($this->child_jqGrid_option)) foreach($this->child_jqGrid_option as $k=>$v)
6101                $grid->set_option($k,$v);
6102            $grid->rownumbers();
6103            $grid->click_grow_row();
6104            $grid->set_option('sortname',$class->list_sortname_dflt);
6105            $grid->set_option('sortorder',$class->list_sortorder_dflt);
6106            $class->col_list_noShow[]=$linkField;
6107            //$class->col_list_noShow[]=$link_este['to_field'];
6108
6109            // exception
6110            if(strpos($table,'_pago') || strpos($table,'_uso')) {
6111                //$view_icon = array('url'=>$this->table.'_pago.php');
6112                $view_icon =array('icon'=>'ui-icon-document','title'=>'Ver detalle'
6113                        ,'isjs'=>true // llama js en vez de url
6114                        ,'dialog'=>true
6115                        ,'url'=>'iajggridDialogParams2PostData'
6116                        ,'params'=>'{iacc:"app_'.$table.'",iactbl:"'.$table.'", iah:"r"}'
6117                        ,'target'=>'_self'
6118                        ,'id'=>'"'.$table.'_id"'
6119                    );
6120
6121                if($editable){ // && $delete
6122                    $view_icon = $class->view_in_actions ? $view_icon : array();
6123                    $actions = array('colName' => 'Act'
6124                    , 'formatoptions' => array('editbutton' => false, 'editformbutton' => false, 'delbutton' => false)
6125                    , 'externView' => false, 'externEdit' => false, 'externView' => false, 'width' => 70
6126                    , 'extern' => $delete ? array('del' => array('isjs' => true, 'icon' => 'ui-icon-trash', 'title' => 'Eliminar pago', 'url' => 'acuenta_pago_del', 'id' => 'elid', 'target' => '', 'params' => 'para'), 'customView' => $view_icon) : array('customView' => $view_icon)
6127                    );
6128                }
6129                else
6130                    $actions=array( 'colName'=>'Act'
6131                                ,'formatoptions'=>array('editbutton'=>false, 'editformbutton'=>false,'delbutton'=>false )
6132                                , 'externView'=>false, 'externEdit'=>false , 'externView'=>false
6133                                ,'extern' => array('customView'=>$view_icon)
6134                                );
6135
6136                if(!empty($extraButtonActions)) foreach($extraButtonActions as $b) {
6137                    $actions['extern'][]=$b;
6138                }
6139            }
6140            // debia ser $class->child_jqGrid_hiddenCols en vez de $class->jqGridHiddenCols, etc...
6141            $grid->colModel_iacase($class,$actions,$class->col_list_noShow,$class->jqGridHiddenCols,array(),$class->child_jqgrid_colModelOverride,array(),$where,true,!$class->primary_key_show,$extraParams,$class->child_jqGrid_cols);
6142
6143            $pager=$this->array_val('gridPager', $link_este,  array('rowNum'=>100,'rowList'=>null,'pgtext'=>'','pgbuttons'=>true,'pginput'=>true) );
6144            if(!array_key_exists('emptyrecords',$pager))
6145                $pager['emptyrecords']="No tiene ".$class->label_table_plural();
6146
6147            $grid->pager( $pager );
6148            $grid->navigator($class, array( 'add'=>$gridAdd,'edit'=>false,'del'=>$gridDelete,'view'=>false,'search'=>true,'refresh'=>true )
6149                ,null,array(),array(),array(),null ); // despues de poner postData ie en colModel_iacase
6150            $grid->column_chooser();
6151            //PONE Los filters en el submit de la forma en que esta el grid. if($class->jqGridFilters)
6152            if($class->jqGridFilters && $this->h!='e' && $this->h!='a'  && $this->h!='s' && $this->h!='i')
6153                $grid->toolbar_filter(true,true,true);
6154            $grid->resize_grid();
6155            // remove close button $('.ui-jqgrid-titlebar-close','#gview_mysimpletable').remove();
6156
6157        $class->child_listme_preRender($grid);
6158
6159        $jsAfter = $class->export_gridvalues($gridId);
6160        $grid->javascriptAfter($jsAfter,'jsAfter');
6161
6162        $grid->render();
6163        if( $child['links_este']['formato']=='addChild' && ($this->h=='e' || $this->h=='a'))
6164            $this->child_table_addonly($class,$grid->gridVar);
6165        $class->child_listme_postRender($grid);
6166    }
6167
6168    function  child_listme_preRender($grid) { }
6169
6170    function  child_listme_postRender($grid) { }
6171
6172    /**
6173     * iacase::child_table_addonly()
6174     *
6175     * @param mixed $class
6176     * @param mixed $gridVar
6177     * @return
6178     */
6179    function child_table_addonly($class,$gridVar) {
6180       $class->conOri=false;
6181       if(!$class->may_insert())
6182            return;
6183       echo PHP_EOL."<div class='addchild'><fieldset id='iacfldset$class->table'><table><tr>";
6184       $enviar='';
6185       foreach($class->campos as $fieldName=>$f)
6186            if($f['modo']!='R/O' && $f['modo']!='Hidden' ) {
6187                $enviar.=','.$class->table.'-'.$fieldName;
6188                echo PHP_EOL."<td>".$class->label_tag($fieldName)."<br />".$class->input_auto($fieldName,array('name'=>$class->table.'-'.$fieldName));
6189            }
6190       $button_label='Enviar';
6191       $enviar=substr($enviar,1);
6192       echo PHP_EOL."<td style='vertical-align:bottom;'><input type=button name=addchld onclick=\"iacAddChld('$this->id','$this->pk_field','".get_class($this)."','".get_class($class)."','$class->table',$gridVar)\" value='$button_label' />";
6193       echo PHP_EOL."</table></fieldset></div>";
6194    }
6195
6196    /**
6197     * iacase::child_table_edit()
6198     *
6199     * @param mixed $table
6200     * @param mixed $conTitle
6201     * @param mixed $childDef
6202     * @param mixed $tag
6203     * @param bool $miniLog
6204     * @param string $orderBy
6205     * @param mixed $table_id
6206     * @param mixed $parent_id
6207     * @param mixed $parent_link
6208     * @param mixed $named
6209     * @param integer $minRows
6210     * @param integer $maxRows
6211     * @return
6212     */
6213    function child_table_edit($table,$conTitle,$childDef,$tag=array(),$miniLog=false,$orderBy='',$table_id=null,$parent_id=null,$parent_link=null
6214                                ,$named=null,$minRows=1,$maxRows=0) {
6215     // edit con addanother
6216        $orderBy='';
6217        if(!$this->child_table_get($table,$table_id,$parent_id,$parent_link,$child_pk,$orderBy,$tag,$child,$class) )
6218            return "$table not found!";
6219        if($named==null)
6220            $named=$table;
6221        global $gIApath;
6222        $ids='';
6223        if($conTitle)
6224            echo "<div align=center>".$class->label."</div>";
6225        $ret= PHP_EOL."<table id='$table_id' class=tablaChild style='width:100%;'><thead><tr>\r\n";
6226        foreach($tag as $fieldName=>$d) {
6227            if( $fieldName!='alta_db' && $fieldName!='alta_por' && $fieldName!='ultimo_cambio'  && $fieldName!='ultimo_cambio_por' )
6228                if( (!array_key_exists('modo',$d) || $d['modo']!='None' ) && (!array_key_exists('para',$d) || $d['para']!='Hidden') && ( !!array_key_exists('notd',$d) || !$d['notd']   ) )
6229                    if( array_key_exists('label',$d) )
6230                        $ret.= "<th  style='".( array_key_exists('tdwidth',$d) ? "width:$d[tdwidth]" : '' )."'>".$d['label'];
6231                    else
6232                        $ret.= "<th style='".(isset($d['tdwidth']) ? "width:$d[tdwidth]" : '' )."'>".$class->label_field($fieldName);
6233        }
6234        $ret.= "<th style='width:16px;'><input type='button' id='add_$table_id' value='+' />".PHP_EOL."</thead><tbody>".PHP_EOL;
6235
6236        //FALTA $virtualCols o mejor a read_record del child
6237        $entries=ia_sqlArrayIndx("SELECT /* iacase:child_table_list */ * FROM $table WHERE $parent_link=".strit($parent_id)." $orderBy");
6238        $irow=0;
6239        if(empty($entries)) {
6240            for($addRows=1;$addRows<=$minRows;$addRows++) {
6241                $ret.= PHP_EOL."<tr>";
6242                foreach($tag as $fieldName=>$d) {
6243                    if( $fieldName!='alta_db' && $fieldName!='alta_por' && $fieldName!='ultimo_cambio'  && $fieldName!='ultimo_cambio_por' )
6244                    if( (!array_key_exists('modo',$d) || $d['modo']!='None' ) && (!array_key_exists('para',$d) || $d['para']!='Hidden')  ) {
6245                        if( !array_key_exists('notd',$d) || !$d['notd'] )
6246                            $ret.= PHP_EOL."<td class='ui-widget-content'>";
6247                        elseif( array_key_exists('label',$d) )
6248                            $ret.='<span>'.$d['label'].' ';
6249                        $ret.= $class->input_auto($fieldName, array('name'=>"$named"."[$irow][$fieldName]") );
6250                        if(array_key_exists('notd',$d) && !$d['notd'] && array_key_exists('label',$d) )
6251                            $ret.='</span>';
6252                    }
6253                }
6254                $ret.= PHP_EOL."<td class='ui-widget-content' style='width:16px;'><img alt='Delete' title='Marcar las que borrar' src='$gIApath[WebPath]img/tache_rojo_plano.gif' class='deleterow d$table_id' />";
6255                    if( array_key_exists($child_pk,$tag) ) {
6256                        $tmp=$named."[".$irow."][".$child_pk."]";
6257                        $ret.="<input type='hidden' id='$tmp' name='$tmp' value='' />";
6258                    }
6259                $ret.='</td>';
6260                $irow++;
6261            }
6262        } else {
6263            $irow=0;
6264            foreach($entries as $chKey=>$chData) {
6265                $ids.=','.$chData[$child_pk];
6266                $ret.= PHP_EOL."<tr>";
6267                $class->ori=$chData;
6268                foreach($tag as $fieldName=>$d)
6269                    if( $fieldName!='alta_db' && $fieldName!='alta_por' && $fieldName!='ultimo_cambio'  && $fieldName!='ultimo_cambio_por' )
6270                    if( (!array_key_exists('modo',$d) || $d['modo']!='None' ) && (!array_key_exists('para',$d) || $d['para']!='Hidden')  ) {
6271                        if(!array_key_exists('notd',$d) || !$d['notd'] )
6272                            $ret.= PHP_EOL."<td class='ui-widget-content'>";
6273                        elseif(array_key_exists('label',$d))
6274                            $ret.='<span>'.$d['label'].' ';
6275                        $ret.= $class->input_auto($fieldName, array('name'=>"$named"."[$irow][$fieldName]"), $chData[$fieldName]);
6276
6277                        if(array_key_exists('notd',$d) && !$d['notd'] && array_key_exists('label',$d) )
6278                            $ret.='</span>';
6279                    }
6280                $ret.= PHP_EOL."<td class='ui-widget-content' style='width:16px;'><img alt='Delete' title='Marcar las que borrar' src='$gIApath[WebPath]img/tache_rojo_plano.gif' class='deleterow d$table_id' />";
6281                if( array_key_exists($child_pk,$chData) ) {
6282                    $tmp=$named."[".$irow."][".$child_pk."]";
6283                    $ret.="<input type='hidden' id='$tmp' name='$tmp' value='".ia_htmlentities($chData[$child_pk])."' />";
6284                }
6285                $ret.='</td>';
6286                $irow++;
6287            }
6288        }
6289
6290        if($childDef['formato']=='addanother')
6291            $ret.= "
6292                </tbody>
6293                </table>
6294                <input type='hidden' name='$named"."_ids' id='$named"."_ids' value='".ia_htmlentities($ids)."' />
6295                <script type='text/javascript'>
6296                    \$(document).ready(function(){\$('#add_$table_id').addanother( '#$table_id', {minRows:$minRows,maxRows:$maxRows,deletelink:'d$table_id'} );});
6297                </script>
6298            ";
6299        else
6300            $ret.="
6301            </tbody>
6302            </table>
6303            <input type='hidden' name='$named"."_ids' id='$named"."_ids' value='".ia_htmlentities($ids)."' />
6304            ";
6305
6306        return $ret;
6307    }
6308
6309
6310    /**
6311     * iacase::child_table_list()
6312     *
6313     * @param mixed $table
6314     * @param bool $conTitle
6315     * @param mixed $tag
6316     * @param bool $miniLog
6317     * @param string $orderBy
6318     * @param mixed $table_id
6319     * @param mixed $parent_id
6320     * @param mixed $parent_link
6321     * @param bool $blankOnEmpty
6322     * @return
6323     */
6324    function child_table_list($table,$conTitle=true,$tag=array(),$miniLog=false,$orderBy='',$table_id=null,$parent_id=null,$parent_link=null,$blankOnEmpty=false) {
6325        $orderBy='';
6326        if(!$this->child_table_get($table,$table_id,$parent_id,$parent_link,$child_pk,$orderBy,$tag,$child,$class) )
6327            return "$table not found!";
6328        if($conTitle)
6329            echo "<div align=center>".$class->label."</div>";
6330        $ret= PHP_EOL."<table id='$table_id' class=tablaChild style='width:99%;'><tr>".PHP_EOL;
6331        foreach($tag as $fieldName=>$d) {
6332            if(  (!isset($d['modo']) || $d['modo']!='None' ) && (!isset($d['notd']) || !$d['notd'] )  )
6333                if(!$miniLog && ($fieldName=='alta_db' || $fieldName=='alta_por' || $fieldName=='ultimo_cambio'  || $fieldName=='ultimo_cambio_por') )
6334                    ;
6335                elseif($miniLog && $fieldName=='alta_por')
6336                    ;
6337                elseif($miniLog && $fieldName=='ultimo_cambio_por')
6338                    ;
6339                elseif($miniLog && $fieldName=='alta_db')
6340                    if( array_key_exists('label',$d) )
6341                        $ret.= "<th class='forma_letreritos'>".$tag[$fieldName]['label'];
6342                    else
6343                        $ret.= "<th class='forma_letreritos'>".$class->label_field($fieldName);
6344                elseif($miniLog && $fieldName=='ultimo_cambio')
6345                    if( array_key_exists('label',$d) )
6346                        $ret.= "<th class='forma_letreritos'>".$tag[$fieldName]['label'];
6347                    else
6348                        $ret.= "<th class='forma_letreritos'>".$class->label_field($fieldName);
6349
6350                elseif( array_key_exists('label',$d) )
6351                    $ret.= "<th class='forma_letreritos'>".$tag[$fieldName]['label'];
6352                else
6353                    $ret.= "<th class='forma_letreritos'>".$class->label_field($fieldName);
6354        }
6355        $irow=0;
6356        //FALTA $virtualCols o mejor a read_record del child
6357        $entries=ia_sqlArrayIndx("SELECT /* iacase:child_table_list */ * FROM $table WHERE $parent_link=".strit($parent_id)." $orderBy");
6358        if(!empty($entries)) {
6359            foreach($entries as $chData) {
6360                $ret.= PHP_EOL."<tr>";
6361                foreach($tag as $fieldName=>$d)
6362                    if( (!array_key_exists('modo',$d) || $d['modo']!='None' )  ) {
6363                        if(!$miniLog && ($fieldName=='alta_db' || $fieldName=='alta_por' || $fieldName=='ultimo_cambio'  || $fieldName=='ultimo_cambio_por') )
6364                            continue;
6365                        if( !($miniLog && ($fieldName=='alta_por' || $fieldName=='ultimo_cambio_por') ) )
6366                            if(!array_key_exists('notd',$d) || !$d['notd'] ) {
6367                                $ret.= "<td class='ui-widget-content'>";
6368                            }
6369                        if(!$miniLog && ($fieldName=='alta_db' || $fieldName=='alta_por' || $fieldName=='ultimo_cambio'  || $fieldName=='ultimo_cambio_por') )
6370                            ;
6371                        elseif($miniLog && $fieldName=='alta_por')
6372                            ;
6373                        elseif($miniLog && $fieldName=='ultimo_cambio_por')
6374                            ;
6375                        elseif($miniLog && $fieldName=='alta_db') {
6376                            $ret.= $class->display($fieldName,array(),$chData[$fieldName] );
6377                            if(array_key_exists('alta_por',$tag) )
6378                                $ret.=' por '.$class->display('alta_por',array(),$chData['alta_por'] );
6379                        } elseif($miniLog && $fieldName=='ultimo_cambio') {
6380                            $ret.= $class->display($fieldName,array(),$chData[$fieldName] );
6381                            if(array_key_exists('ultimo_cambio_por',$tag) )
6382                                $ret.=' por '.$class->display('ultimo_cambio_por',array(),$chData['ultimo_cambio_por'] );
6383                        } else
6384                            $ret.= $class->display($fieldName,array(),$chData[$fieldName] );
6385                    }
6386                $irow++;
6387            }
6388        } elseif($blankOnEmpty)
6389            return '';
6390        return $ret.PHP_EOL.'</table>'.PHP_EOL;
6391    }
6392
6393    /**
6394     * iacase::exporta_listado_csv()
6395     *
6396     * @param bool $conPK
6397     * @param string $whereOrderBy
6398     * @param mixed $sql
6399     * @return
6400     */
6401    public function exporta_listado_csv($conPK=false,$whereOrderBy='',$sql=null) {
6402        header("Content-Type: text/html; charset=utf-8");
6403        header("Cache-Control: no-store, no-cache");
6404        header("Content-Disposition: attachment; filename*=UTF-8''".$this->table.".csv");
6405        echo "\xEF\xBB\xBF";
6406        if(empty($sql))
6407            // falta $virtualCols
6408            $sql="SELECT /* iacase:exporta_csv */ $this->cols_export FROM $this->table $whereOrderBy";
6409        $exporta=ia_sqlArrayIndx($sql);
6410        if(!empty($exporta)) {
6411            foreach($exporta as $rec) {
6412                $con=false;
6413                foreach($rec as $fieldName=>$v) if($conPK || (!$conPK && $fieldName!=$this->pk_field)) if($fieldName!='pwd') {
6414                    if($con)
6415                        echo ','.comillea(to_label($fieldName));
6416                    else {
6417                        echo comillea(to_label($fieldName));
6418                        $con=true;
6419                    }
6420                }
6421                break;
6422            }
6423
6424            foreach($exporta as $rec) {
6425                echo PHP_EOL;
6426                $con=false;
6427                foreach($rec as $fieldName=>$v) if($conPK || (!$conPK && $fieldName!=$this->pk_field)) if($fieldName!='pwd') {
6428                    if( is_numeric($v) )
6429                        if($con)
6430                            echo ','.$v;
6431                        else {
6432                            echo $v;
6433                            $con=true;
6434                        }
6435                    else
6436                    if($con)
6437                        echo ','.comillea($v);
6438                    else {
6439                        echo comillea($v);
6440                        $con=true;
6441                    }
6442                }
6443            }
6444            echo PHP_EOL;
6445        }
6446        die();
6447    }
6448
6449    /**
6450     * iacase::campos_reorder()
6451     *
6452     * @param mixed $newOrder
6453     * @return
6454     */
6455    function campos_reorder($newOrder) {
6456        $new=array();
6457        foreach($newOrder as $fieldName)
6458            if(array_key_exists($fieldName,$this->campos))
6459                $new[$fieldName]=$this->campos[$fieldName];
6460        foreach($this->campos as $fieldName=>$f)
6461            if(!array_key_exists($fieldName,$new))
6462                $new[$fieldName]=$f;
6463        $this->campos=$new;
6464    }
6465
6466    function simulated_fields(&$camposNew,$sql) {
6467        if(function_exists('getMetaData'))
6468            $this->simulated_fields_mysqli($camposNew,$sql);
6469        else
6470            $this->simulated_fields_mysql($camposNew,$sql);
6471    }
6472
6473    function simulated_fields_mysqli(&$camposNew,$sql) {
6474        $ipos = stripos($sql,"ORDER BY");
6475        if($ipos>1) {
6476            $sql = substr($sql,0,$ipos);
6477        }
6478        $info = getMetaData($sql." LIMIT 1");
6479        foreach($info as $fieldName => $field) {
6480            if(!array_key_exists($fieldName,$this->campos)) {
6481                $camposNew[$fieldName]=array();
6482                $camposNew[$fieldName]['modo']='R/O';
6483                $camposNew[$fieldName]['formato']='';
6484                $camposNew[$fieldName]['dontsearch']=true;
6485                $camposNew[$fieldName]['Type']=$field['type'];
6486                if( array_key_exists('numeric', $field) && $field['numeric'] ) {
6487                    $camposNew[$fieldName]['numeric']=true;
6488                    $camposNew[$fieldName]['enteros']=$field['integers'];
6489                    $camposNew[$fieldName]['decimales']=0;
6490                    //$camposNew[$fieldName]['decimales']=strpos($type,'unsigned')!==FALSE;
6491                }
6492            } else {
6493                $camposNew[$fieldName]=$this->campos[$fieldName];
6494            }
6495        }
6496    }
6497
6498    function simulated_fields_mysql(&$camposNew,$sql) {
6499        return;
6500        /**
6501        $result = ia_result($sql." LIMIT 1");
6502        $fields = mysql_num_fields($result);
6503        for ($i=0; $i < $fields; $i++) {
6504            $fieldName=mysql_field_name($result, $i);
6505            if(substr($fieldName,0,5)=='sino_') {
6506                $fieldName=substr($fieldName,5);
6507                $enumSiNo=true;
6508            } else
6509                $enumSiNo=false;
6510            if(!array_key_exists($fieldName,$this->campos)) {
6511                $camposNew[$fieldName]=array();
6512                $camposNew[$fieldName]['modo']='R/O';
6513                $camposNew[$fieldName]['formato']='';
6514                $camposNew[$fieldName]['dontsearch']=true;
6515
6516                $type=mysql_field_type($result, $i);
6517                if($enumSiNo) {
6518                    //$type='enum';
6519                    //$camposNew[$fieldName]['options_array']=   array ('Si' => 'Si','No' => 'No');
6520                }
6521                $camposNew[$fieldName]['Type']=$type;
6522                if( strpos($type,'int')!==FALSE || strpos($type,'year')!==FALSE ) {
6523                    $camposNew[$fieldName]['numeric']=true;
6524                    $camposNew[$fieldName]['enteros']=mysql_field_len($result, $i);
6525                    $camposNew[$fieldName]['decimales']=0;
6526                    $camposNew[$fieldName]['decimales']=strpos($type,'unsigned')!==FALSE;
6527                }
6528                if( strpos($type,'decimal')!==FALSE || strpos($type,'real')!==FALSE ) {
6529                    $camposNew[$fieldName]['numeric']=true;
6530                    $camposNew[$fieldName]['enteros']=mysql_field_len($result, $i);
6531                    $camposNew[$fieldName]['decimales']=2;
6532                    $camposNew[$fieldName]['decimales']=strpos($type,'unsigned')!==FALSE;
6533                }
6534            } else $camposNew[$fieldName]=$this->campos[$fieldName];
6535        }
6536        **/
6537    }
6538
6539}