Added dimension edition on purchase invoice entry.
[fa-stable.git] / sql / alter2.4.php
1 <?php
2 /**********************************************************************
3     Copyright (C) FrontAccounting, LLC.
4         Released under the terms of the GNU General Public License, GPL, 
5         as published by the Free Software Foundation, either version 3 
6         of the License, or (at your option) any later version.
7     This program is distributed in the hope that it will be useful,
8     but WITHOUT ANY WARRANTY; without even the implied warranty of
9     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  
10     See the License here <http://www.gnu.org/licenses/gpl-3.0.html>.
11 ***********************************************************************/
12 function collations_list_row($label, $name, $selected_id=null)
13 {
14
15 $mysql_collations = array(
16   'xx' => 'Unicode (multilanguage)',
17   'is' => 'Icelandic',
18   'lv' => 'Latvian',
19   'ro' => 'Romanian',
20   'sl' => 'Slovenian',
21   'pl' => 'Polish',
22   'et' => 'Estonian',
23   'es' => 'Spanish', // or 'spanish2',
24   'sw' => 'Swedish',
25   'tr' => 'Turkish',
26   'cs' => 'Czech',
27   'da' => 'Danish',
28   'lt' => 'Lithuanian',
29   'sk' => 'Slovak',
30   'sp' => 'Spanish (alternative)',
31   'fa' => 'Persian',
32   'hu' => 'Hungarian',
33   'fr' => 'French',
34   'it' => 'Italian',
35 );
36
37         echo "<tr>";
38         if ($label != null)
39                 echo "<td class='label'>$label</td>\n";
40         echo "<td>";
41
42         echo array_selector($name, $selected_id, $mysql_collations, 
43                 array('select_submit'=> false) );
44         echo "</td></tr>\n";
45 }
46
47 class fa2_4 extends fa_patch {
48         var $previous = '2.3rc';                // applicable database version
49         var $version = '2.4.0'; // version installed
50         var $description;
51         var $sql = 'alter2.4.sql';
52         var $preconf = true;
53         
54         function fa2_4() {
55                 parent::fa_patch();
56                 $this->description = _('Upgrade from version 2.3 to 2.4');
57         }
58         
59     /*
60             Shows parameters to be selected before upgrade (if any)
61         */
62     function show_params($comp)
63         {
64           display_note(_('Set optimal parameters and start upgrade:'));
65           start_table(TABLESTYLE);
66           start_row();
67                 collations_list_row(_('Text collation optimization:'), 'collation', substr($_SESSION['language']->code, 0, 2));
68           end_row();
69           end_table();
70           br();
71     }
72
73         /*
74             Fetches selected upgrade parameters.
75     */
76         function prepare()
77     {
78                 $this->collation = get_mysql_collation(get_post('collation'));
79                 return true;
80         }
81
82         //
83         //      Install procedure. All additional changes 
84         //      not included in sql file should go here.
85         //
86         function install($company, $force=false)
87         {
88                 global $db_version, $db_connections;
89
90                 $pref = $db_connections[$company]['tbpref'];
91
92                 if (get_company_pref('grn_clearing_act') === null) { // available form 2.3.1, can be not defined on pre-2.4 installations
93                         set_company_pref('grn_clearing_act', 'glsetup.purchase', 'varchar', 15, 0);
94                 }
95                 if (get_company_pref('default_quote_valid_days') === null) { // new in 2.3.23 installations
96                         set_company_pref('default_quote_valid_days', 'glsetup.sales', 'smallint', 6, 30);
97                 }
98                 if (get_company_pref('bcc_email') === null) { // available from 2.3.14, can be not defined on pre-2.4 installations
99                         set_company_pref('bcc_email', 'setup.company', 'varchar', 100, '');
100                 }
101                 if (get_company_pref('alternative_tax_include_on_docs') === null) { // available from 2.3.14, can be not defined on pre-2.4 installations
102                         set_company_pref('alternative_tax_include_on_docs', 'setup.company', 'tinyint', 1, '0');
103                 }
104                 if (get_company_pref('suppress_tax_rates') === null) { // available from 2.3.14, can be not defined on pre-2.4 installations
105                         set_company_pref('suppress_tax_rates', 'setup.company', 'tinyint', 1, '0');
106                 }
107
108                 $result = $this->update_workorders()  && $this->update_grn_rates() && $this->switch_database_to_utf($pref);
109
110                 if ($result)
111                         $result = $this->do_cleanup();
112
113                 return $result;
114         }
115
116         //
117         // optional procedure done after upgrade fail, before backup is restored
118         //
119         function post_fail($company)
120         {
121                 $pref = $this->companies[$company]['tbpref'];
122                 db_query("DROP TABLE IF EXISTS " . $pref . 'wo_costing');
123         }
124
125         function update_workorders()
126         {
127                 global $db;
128
129                 $sql = "SELECT DISTINCT type, type_no, tran_date, person_id FROM ".TB_PREF."gl_trans WHERE `type`=".ST_WORKORDER
130                 ." AND person_type_id=1";
131                 $res = db_query($sql);
132                 if (!$res)
133                         return $this->log_error(sprintf(_("Cannot update work orders costs:\n%s"), db_error_msg($db)));
134
135                 while ($row = db_fetch($res))
136                 {
137                         $journal_id = get_next_trans_no(ST_JOURNAL);
138
139                         $sql1 = "UPDATE ".TB_PREF."gl_trans SET `type`=".ST_JOURNAL.", type_no={$journal_id},
140                                 person_type_id=NULL, person_id=0
141                                 WHERE `type`=".ST_WORKORDER." AND type_no={$row['type_no']} AND tran_date='{$row['tran_date']}'
142                                 AND person_id='{$row['person_id']}'";
143                         if (!db_query($sql1)) return false;
144
145                         $sql2 = "INSERT INTO ".TB_PREF."wo_costing (workorder_id, cost_type, trans_no) 
146                                 VALUES ({$row['type_no']}, {$row['person_id']}, {$journal_id})";
147                         if (!db_query($sql2)) return false;
148                 }
149                 return true;
150         }
151
152 /*
153         In previous versions FA ignored encoding settings on database/tables, so it depended on server settings,
154         but data stored is encoded in user language encoding. Now we switch to utf8 internal database encoding, while
155         user encoding can be selected independently.
156
157         To perform safe FA database switch to utf-8 encoding we have to first ensure that all text/char columns 
158         have properly set encoding (the same as its content), so the algorithm performed on every table is as follows:
159         . set default table encoding for the table to currently used on client side;
160         . for all text/char column:
161          - suppress autorecoding by change of the type to related binary/blob type
162          - change column to utf8 encodding and selected collation.
163         . change default table encoding to utf8 and selected collation
164 */
165         function switch_database_to_utf($pref, $dbg = false) {
166
167                 global $installed_languages, $dflt_lang;
168
169                 $old_encoding = 'latin1'; // default client encoding
170
171                  // site default encoding is presumed as encoding for all databases!
172                 $lang = array_search_value($dflt_lang, $installed_languages, 'code');
173                 $new_encoding = get_mysql_encoding_name(strtoupper($lang['encoding']));
174
175                 $this->log_error(sprintf('Switching database to utf8 encoding from %s', $old_encoding), 'Info');
176                 $collation = $this->collation;
177                 $tsql = "SHOW TABLES LIKE '".($pref=='' ? '' : substr($pref, 0, -1).'\\_')."%'";
178                 $tresult = db_query($tsql, "Cannot select all tables with prefix '$pref'");
179                 while($tbl = db_fetch($tresult)) {
180                         $table = $tbl[0];
181
182                         db_query("ALTER TABLE `$table` CONVERT TO CHARACTER SET $old_encoding"); // convert encoding on utf-8 tables
183
184                         // set proper default table encoding for current user language (used on binary->text conversion)
185                         db_query("ALTER TABLE `$table` CHARSET $new_encoding");
186                         $csql = "SHOW COLUMNS FROM $table";
187                         $cresult = db_query($csql, "Cannot select column names for table '$table'");
188                         $convert = false;
189
190                         $to_binary = $to_default = $to_utf = array();
191                         while($col = db_fetch($cresult)) {
192
193                                 $bintype = strtr($col['Type'], array('varchar' => 'varbinary', 'char'=>'varbinary', 'text'=>'blob', 'tinytext'=>'tinyblob'));
194
195                                 if ($bintype != $col['Type'])
196                                 { // this is char/text column, so change encoding to proper encoding
197                                         if ($dbg)
198                                                 $this->log_error(sprintf('%s switched to uft8.', $table.'.'.$col['Field']), 'Debug');
199
200                                         $null = $col['Null'] === 'YES' ? ' NULL ' : ' NOT NULL ';
201                                         $default = $col['Null'] !== 'YES' && isset($col['Default']) ? ' DEFAULT '.db_escape($col['Default']) : '';
202
203                                         // to avoid column width multiplication x3 we old->binary->ui->utf column type change instead of column CONVERT
204
205                                         $to_binary[] = "CHANGE `".$col['Field']."` `".$col['Field']."` ".$bintype;
206                                         $to_default[] = "CHANGE `".$col['Field']."` `".$col['Field']."` ".$col['Type'].$null.$default;
207                                         $to_utf[] = "MODIFY COLUMN `".$col['Field']."` ".$col['Type']." COLLATE ".$collation.$null.$default;
208                                         $convert = true;
209                                 }
210                         }
211                         if(count($to_binary))
212                         {
213                                 $sql = "ALTER TABLE `$table` ".implode(',',$to_binary);
214                                 db_query($sql);
215                                 $sql = "ALTER TABLE `$table` ".implode(',',$to_default);
216                                 db_query($sql);
217                                 $sql = "ALTER TABLE `$table` ".implode(',',$to_utf);
218                                 db_query($sql);
219                         }
220                         db_query("ALTER TABLE `$table` COLLATE $collation");
221                 }
222                 db_query("ALTER DATABASE COLLATE $collation");
223                 $this->log_error(_('Convertion to utf8 done.'), 'Info');
224
225                 return true;
226         }
227
228         function update_grn_rates()
229         {
230                 $sql = "SELECT grn.id, grn.delivery_date, supp.curr_code 
231                         FROM ".TB_PREF."grn_batch grn, ".TB_PREF."suppliers supp
232                         WHERE supp.supplier_id=grn.supplier_id AND supp.curr_code!='".get_company_pref('curr_default')."'";
233                 $result = db_query($sql);
234
235                 if (!$result)
236                         return false;
237
238                 $sql = "UPDATE ".TB_PREF."grn_batch SET rate=%s WHERE id=%d";
239                 while ($grn = db_fetch($result))
240                         db_query(sprintf($sql, get_exchange_rate_from_home_currency($grn['curr_code'], sql2date($grn['delivery_date'])), $grn['id']));
241
242                 return true;
243         }
244
245         function do_cleanup()
246         {
247                 global $db;
248
249                 //remove obsolete and temporary columns.
250                 // this have to be done here as db_import rearranges alter query order
251                 $dropcol = array(
252                                 'tax_group_items' => array('rate'),
253                                 'budget_trans' => array('type', 'type_no', 'person_id', 'person_type_id', 'memo_'),
254                                 'cust_branch' => array('contact_name', 'disable_trans'),
255                 );
256
257                 foreach($dropcol as $table => $columns)
258                         foreach($columns as $col) {
259                                 if (db_query("ALTER TABLE `".TB_PREF."{$table}` DROP `$col`") == false) {
260                                         return $this->log_error(sprintf(_("Cannot drop column in %s table: %s"), $table, db_error_msg($db)));
261                                 }
262                         }
263                 return true;
264   }
265 }
266
267 $install = new fa2_4;