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 ***********************************************************************/
13 var $version = '2.3'; // version installed
15 var $sql = 'alter2.3.sql';
17 var $beta = false; // upgrade from 2.2 or 2.3beta;
20 $this->description = _('Upgrade from version 2.2 to 2.3');
24 // Install procedure. All additional changes
25 // not included in sql file should go here.
27 function install($pref, $force)
32 // all specials below are already done on 2.3beta
34 $sql = "SELECT debtor_no, payment_terms FROM {$pref}debtors_master";
36 $result = db_query($sql);
38 display_error("Cannot read customers"
39 .':<br>'. db_error_msg($db));
42 // update all sales orders and transactions with customer std payment terms
43 while($cust = db_fetch($result)) {
44 $sql = "UPDATE {$pref}debtor_trans SET "
45 ."payment_terms = '" .$cust['payment_terms']
46 ."' WHERE debtor_no='".$cust['debtor_no']."'";
47 if (db_query($sql)==false) {
48 display_error("Cannot update cust trans payment"
49 .':<br>'. db_error_msg($db));
52 $sql = "UPDATE {$pref}sales_orders SET "
53 ."payment_terms = '" .$cust['payment_terms']
54 ."' WHERE debtor_no='".$cust['debtor_no']."'";
55 if (db_query($sql)==false) {
56 display_error("Cannot update sales order payment"
57 .':<br>'. db_error_msg($db));
61 if (!$this->update_totals($pref)) {
62 display_error("Cannot update order totals");
65 if (!$this->update_line_relations($pref)) {
66 display_error("Cannot update sales document links");
69 //remove obsolete and temporary columns.
70 // this have to be done here as db_import rearranges alter query order
72 'crm_persons' => array('tmp_id','tmp_class'),
73 'debtors_master' => array('email'),
74 'cust_branch' => array('phone', 'phone2', 'fax', 'email'),
75 'suppliers' => array('phone', 'phone2', 'fax', 'email'),
76 'debtor_trans' => array('trans_link')
79 foreach($dropcol as $table => $columns)
80 foreach($columns as $col) {
81 if (db_query("ALTER TABLE `{$pref}{$table}` DROP `$col`")==false) {
82 display_error("Cannot drop {$table}.{$col} column:<br>".db_error_msg($db));
86 // remove old preferences table after upgrade script has been executed
87 $sql = "DROP TABLE IF EXISTS `{$pref}company`";
91 return update_company_prefs(array('version_id'=>$core_version), $pref);
94 // Checking before install
96 function pre_check($pref, $force)
98 if ($this->beta && !$force)
99 $this->sql = 'alter2.3rc.sql';
104 // Test if patch was applied before.
106 function installed($pref) {
107 $this->beta = !check_table($pref, 'suppliers', 'tax_included');
109 $n = 1; // number of patches to be installed
114 if (!check_table($pref, 'comments', 'type', array('Key'=>'MUL'))) $patchcnt++;
115 if (!check_table($pref, 'sys_prefs')) $patchcnt++;
116 if (!check_table($pref, 'sales_orders', 'payment_terms')) $patchcnt++;
118 if (!check_table($pref, 'purch_orders', 'tax_included')) $patchcnt++;
119 return $n == $patchcnt ? true : ($patchcnt ? ($patchcnt.'/'. $n) : 0);
121 //=========================================================================================
122 // 2.3 specific update functions
128 function update_totals($pref)
130 global $path_to_root;
132 include_once("$path_to_root/sales/includes/cart_class.inc");
133 include_once("$path_to_root/purchasing/includes/po_class.inc");
134 $cart = new cart(ST_SALESORDER);
135 $sql = "SELECT order_no FROM {$pref}sales_orders";
136 $orders = db_query($sql);
140 while ($order_no = db_fetch($orders)) {
141 read_sales_order($order_no[0], $cart, ST_SALESORDER);
142 $result = db_query("UPDATE {$pref}sales_orders SET total=".$cart->get_trans_total());
143 unset($cart->line_items);
146 $cart = new purch_order();
147 $sql = "SELECT order_no FROM {$pref}purch_orders";
148 $orders = db_query($sql);
151 while ($order_no = db_fetch($orders)) {
152 read_po($order_no[0], $cart);
153 $result = db_query("UPDATE {$pref}purch_orders SET total=".$cart->get_trans_total());
154 unset($cart->line_items);
159 //------------------------------------------------------------------------------
160 // Retreive parent document number(s) for given transaction
162 function get_parent_trans_2_2($trans_type, $trans_no) {
164 $sql = 'SELECT trans_link FROM
165 '.TB_PREF.'debtor_trans WHERE trans_no='.db_escape($trans_no)
166 .' AND type='.db_escape($trans_type).' AND trans_link!=0';
168 $result = db_query($sql, 'Parent document numbers cannot be retrieved');
170 if (db_num_rows($result)) {
171 $link = db_fetch($result);
172 return array($link['trans_link']);
174 if ($trans_type!=ST_SALESINVOICE) return 0; // this is credit note with no parent invoice
175 // invoice: find batch invoice parent trans.
176 $sql = 'SELECT trans_no FROM
177 '.TB_PREF.'debtor_trans WHERE
178 (trans_link='.db_escape($trans_no).' AND type='. get_parent_type($trans_type) .')';
180 $result = db_query($sql, 'Delivery links cannot be retrieved');
183 if(db_num_rows($result)>0) {
184 while($link = db_fetch($result)) {
185 $delivery[] = $link['trans_no'];
188 return count($delivery) ? $delivery : 0;
192 Reorganizing document relations. Due to the design issue in pre 2.3 db structure
193 there can be sales documents with lines not properly linked to parents. This rare
194 cases will be described in error log.
196 function update_line_relations($pref)
198 global $path_to_root, $systypes_array;
200 require_once("$path_to_root/includes/sysnames.inc");
202 $sql = "SELECT d.type, trans_no, order_ FROM {$pref}debtor_trans d
203 LEFT JOIN {$pref}voided v ON d.type=v.type AND d.trans_no=v.id
204 WHERE ISNULL(v.type) AND
205 (d.type=".ST_CUSTDELIVERY
206 ." OR d.type=".ST_SALESINVOICE
207 ." OR d.type=".ST_CUSTCREDIT.")";
208 $result = db_query($sql);
212 while ($trans = db_fetch($result)) {
213 $type = $trans['type'];
214 $trans_no = $trans['trans_no'];
218 $lines = get_customer_trans_details($type, $trans_no);
219 $n = db_num_rows($lines);
221 if ($type==ST_CUSTDELIVERY)
222 $src_lines = get_sales_order_details($trans['order_'], ST_SALESORDER);
224 $src_lines = get_customer_trans_details(get_parent_type($type),
225 $this->get_parent_trans_2_2($type, $trans_no));
227 $src_n = db_num_rows($src_lines);
229 if (($type == ST_CUSTCREDIT) && ($src_n == 0))
230 continue; // free credit note has no src lines
232 $max = $type == ST_CUSTDELIVERY ? $n : max($src_n, $n);
234 for($i = 0, $j=0; $i < $max; $i++) {
235 if (!($doc_line = @db_fetch($lines)))
238 if(!($src_line = @db_fetch($src_lines)))
241 if ($type == ST_CUSTDELIVERY)
242 $src_line['stock_id'] = $src_line['stk_code']; // SO details has another field name
244 if ($src_line['stock_id'] == $doc_line['stock_id']
245 && ($src_line['quantity'] >= $doc_line['quantity'])) {
247 $sql = "UPDATE {$pref}debtor_trans_details SET src_id = {$src_line['id']}
248 WHERE id = {$doc_line['id']}";
255 error_log("Line level relations error for ".$systypes_array[$type]." #$trans_no.");
262 $install = new fa2_3;