[3594] | 1 | <?php |
---|
| 2 | /** |
---|
| 3 | * ProjectManager - Pricelist user interface |
---|
| 4 | * |
---|
| 5 | * @link http://www.egroupware.org |
---|
| 6 | * @author Ralf Becker <RalfBecker-AT-outdoor-training.de> |
---|
| 7 | * @package projectmanager |
---|
| 8 | * @copyright (c) 2005 by Ralf Becker <RalfBecker-AT-outdoor-training.de> |
---|
| 9 | * @license http://opensource.org/licenses/gpl-license.php GPL - GNU General Public License |
---|
| 10 | * @version $Id: class.uipricelist.inc.php 22355 2006-08-26 16:30:45Z ralfbecker $ |
---|
| 11 | */ |
---|
| 12 | |
---|
| 13 | include_once(PHPGW_INCLUDE_ROOT.'/projectmanager/inc/class.bopricelist.inc.php'); |
---|
| 14 | include_once(PHPGW_INCLUDE_ROOT.'/etemplate/inc/class.uietemplate.inc.php'); |
---|
| 15 | |
---|
| 16 | /** |
---|
| 17 | * Pricelist user interface of the projectmanager |
---|
| 18 | */ |
---|
| 19 | class uipricelist extends bopricelist |
---|
| 20 | { |
---|
| 21 | /** |
---|
| 22 | * Functions callable via menuaction |
---|
| 23 | * |
---|
| 24 | * @var unknown_type |
---|
| 25 | */ |
---|
| 26 | var $public_functions = array( |
---|
| 27 | 'index' => true, |
---|
| 28 | 'view' => true, |
---|
| 29 | 'edit' => true, |
---|
| 30 | ); |
---|
| 31 | var $billable_lables = array('bookable','billable'); |
---|
| 32 | /** |
---|
| 33 | * Constructor, calls the constructor of the extended class |
---|
| 34 | * |
---|
| 35 | * @param int $pm_id=null project to use |
---|
| 36 | * @return uipricelist |
---|
| 37 | */ |
---|
| 38 | function uipricelist($pm_id=null) |
---|
| 39 | { |
---|
| 40 | if (!is_null($pm_id) || isset($_REQUEST['pm_id'])) |
---|
| 41 | { |
---|
| 42 | if (is_null($pm_id)) $pm_id = (int) $_REQUEST['pm_id']; |
---|
| 43 | $GLOBALS['phpgw']->session->appsession('pm_id','projectmanager',$pm_id); |
---|
| 44 | } |
---|
| 45 | else |
---|
| 46 | { |
---|
| 47 | $pm_id = (int) $GLOBALS['phpgw']->session->appsession('pm_id','projectmanager'); |
---|
| 48 | } |
---|
| 49 | $this->bopricelist($pm_id); // sets $this->pm_id |
---|
| 50 | } |
---|
| 51 | |
---|
| 52 | function view() |
---|
| 53 | { |
---|
| 54 | return $this->edit(null,true); |
---|
| 55 | } |
---|
| 56 | |
---|
| 57 | function edit($content=null,$view=false,$msg='') |
---|
| 58 | { |
---|
| 59 | $tpl =& new etemplate('projectmanager.pricelist.edit'); |
---|
| 60 | $tabs = 'price|project|description'; |
---|
| 61 | |
---|
| 62 | if (!is_array($content)) |
---|
| 63 | { |
---|
| 64 | if (($pl_id = (int) $_GET['pl_id']) && $this->read(array( |
---|
| 65 | 'pl_id' => $pl_id, |
---|
| 66 | 'pm_id' => $this->pm_id ? array($this->pm_id,0) : 0, |
---|
| 67 | ))) |
---|
| 68 | { |
---|
| 69 | |
---|
| 70 | // perms are checked later, see view_...prices |
---|
| 71 | } |
---|
| 72 | else // add new price |
---|
| 73 | { |
---|
| 74 | $pl_id = 0; |
---|
| 75 | $view = false; |
---|
| 76 | $this->data = array( |
---|
| 77 | 'prices' => array(), |
---|
| 78 | 'project_prices' => array(), |
---|
| 79 | 'pm_id' => $this->pm_id, |
---|
| 80 | ); |
---|
| 81 | } |
---|
| 82 | // no READ or EDIT/ADD rights ==> close the popup |
---|
| 83 | if (!$this->check_acl($view ? PHPGW_ACL_READ : PHPGW_ACL_EDIT) && |
---|
| 84 | !($this->pm_id && $this->check_acl($view ? PHPGW_ACL_READ : PHPGW_ACL_EDIT,$this->pm_id))) |
---|
| 85 | { |
---|
| 86 | $js = "alert('".lang('Permission denied !!!')."'); window.close();"; |
---|
| 87 | $GLOBALS['phpgw']->common->phpgw_header(); |
---|
| 88 | echo "<script>\n$js\n</script>\n"; |
---|
| 89 | $GLOBALS['phpgw']->common->phpgw_exit(); |
---|
| 90 | } |
---|
| 91 | if (count($this->data['project_prices'])) $content[$tabs] = 'project'; // open project tab |
---|
| 92 | $pm_id = count($this->data['project_prices']) ? $this->data['project_prices'][0]['pm_id'] : $this->pm_id; |
---|
| 93 | } |
---|
| 94 | else |
---|
| 95 | { |
---|
| 96 | $this->data = $content; |
---|
| 97 | foreach(array('view','button','delete_price','delete_project_price',$tabs) as $key) |
---|
| 98 | { |
---|
| 99 | unset($this->data[$key]); |
---|
| 100 | } |
---|
| 101 | $pl_id = $content['pl_id']; |
---|
| 102 | $pm_id = $content['pm_id']; |
---|
| 103 | // copy only non-empty and not deleted prices to $this->data[*prices] |
---|
| 104 | foreach(array('prices' => 1,'project_prices' => 3) as $name => $row) |
---|
| 105 | { |
---|
| 106 | $this->data[$name] = array(); |
---|
| 107 | $delete =& $content[$name == 'prices' ? 'delete_price' : 'delete_project_price']; |
---|
| 108 | while (isset($content[$name][$row])) |
---|
| 109 | { |
---|
| 110 | $price = $content[$name][$row]; |
---|
| 111 | if ($price['pl_price'] && !$delete[$row]) |
---|
| 112 | { |
---|
| 113 | $this->data[$name][] = $price; |
---|
| 114 | } |
---|
| 115 | ++$row; |
---|
| 116 | } |
---|
| 117 | } |
---|
| 118 | if (!$this->data['pl_unit']) $this->data['pl_unit'] = lang('h'); |
---|
| 119 | |
---|
| 120 | list($button) = @each($content['button']); |
---|
| 121 | switch($button) |
---|
| 122 | { |
---|
| 123 | case 'save': |
---|
| 124 | case 'apply': |
---|
| 125 | if (!($err = $this->save())) |
---|
| 126 | { |
---|
| 127 | $msg = lang('Price saved'); |
---|
| 128 | } |
---|
| 129 | else |
---|
| 130 | { |
---|
| 131 | $msg = lang('Error: saving the price (%1) !!!',$err); |
---|
| 132 | $button = 'apply'; // dont close the window |
---|
| 133 | } |
---|
| 134 | $js = "window.opener.location.href='".$GLOBALS['phpgw']->link('/index.php',array( |
---|
| 135 | 'menuaction' => 'projectmanager.uipricelist.index', |
---|
| 136 | 'msg' => $msg, |
---|
| 137 | ))."';"; |
---|
| 138 | if ($button == 'apply') break; |
---|
| 139 | // fall through |
---|
| 140 | case 'cancel': |
---|
| 141 | $js .= 'window.close();'; |
---|
| 142 | echo '<html><body onload="'.$js.'"></body></html>'; |
---|
| 143 | $GLOBALS['phpgw']->common->phpgw_exit(); |
---|
| 144 | break; |
---|
| 145 | |
---|
| 146 | case 'edit': |
---|
| 147 | $view = false; // acl is ensured later, see $view_*prices |
---|
| 148 | break; |
---|
| 149 | } |
---|
| 150 | } |
---|
| 151 | $view_prices = $view || count($this->data['prices']) && !$this->check_acl(PHPGW_ACL_EDIT); |
---|
| 152 | $view_project_prices = $view || !$this->check_acl(PHPGW_ACL_EDIT,$this->pm_id); |
---|
| 153 | $view = $view || $view_prices && $view_project_prices; // nothing to edit => no rights |
---|
| 154 | |
---|
| 155 | $content = $this->data + array( |
---|
| 156 | 'msg' => $msg, |
---|
| 157 | 'js' => $js ? "<script>\n".$js."\n</script>" : '', |
---|
| 158 | 'view' => $view, |
---|
| 159 | 'view_prices' => $view_prices, |
---|
| 160 | 'view_project_prices' => $view_project_prices, |
---|
| 161 | $tabs => $content[$tabs], |
---|
| 162 | ); |
---|
| 163 | // adjust index and add empty price-lines for adding new prices |
---|
| 164 | $content['prices'] = array_merge(array(1),$view_prices ? array() : array(array('pl_price'=>'')),$this->data['prices']); |
---|
| 165 | $content['project_prices'] = array_merge(array(1,2,3),$view_project_prices ? array() : array(array('pl_price'=>'')),$this->data['project_prices']); |
---|
| 166 | |
---|
| 167 | $preserv = $this->data + array( |
---|
| 168 | 'view' => $view, |
---|
| 169 | ); |
---|
| 170 | if (!$this->data['pm_id']) $preserv['pm_id'] = $this->pm_id; |
---|
| 171 | |
---|
| 172 | $readonlys = array( |
---|
| 173 | 'button[delete]' => !$pl_id || !$this->check_acl(PHPGW_ACL_EDIT_BUDGET,$pl_id), |
---|
| 174 | ); |
---|
| 175 | // preserv the "real" prices, with there new keys |
---|
| 176 | foreach(array('prices','project_prices') as $name) |
---|
| 177 | { |
---|
| 178 | unset($preserv[$name]); |
---|
| 179 | foreach($content[$name] as $key => $price) |
---|
| 180 | { |
---|
| 181 | if (is_array($price) && count($price) > 1) |
---|
| 182 | { |
---|
| 183 | $preserv[$name][$key] = $price; |
---|
| 184 | } |
---|
| 185 | } |
---|
| 186 | } |
---|
| 187 | // set general data and price readonly, if $view or price belongs to general pricelist and no edit there |
---|
| 188 | if ($view || count($this->data['prices']) && !$this->check_acl(PHPGW_ACL_EDIT)) |
---|
| 189 | { |
---|
| 190 | foreach($this->db_cols as $name => $data) |
---|
| 191 | { |
---|
| 192 | $readonlys[$name] = true; |
---|
| 193 | } |
---|
| 194 | for($n = 0; $n <= count($this->data['prices']); ++$n) |
---|
| 195 | { |
---|
| 196 | $readonlys['prices['.(1+$n).'][pl_price]'] = |
---|
| 197 | $readonlys['prices['.(1+$n).'][pl_validsince]'] = true; |
---|
| 198 | } |
---|
| 199 | } |
---|
| 200 | // set project-spez. prices readonly, if view or no edit-rights there |
---|
| 201 | if ($view || !$this->check_acl(PHPGW_ACL_EDIT,$this->pm_id)) |
---|
| 202 | { |
---|
| 203 | foreach(array('pl_billable','pl_customertitle') as $name) |
---|
| 204 | { |
---|
| 205 | $readonlys[$name] = true; |
---|
| 206 | } |
---|
| 207 | for($n = 0; $n <= count($this->data['project_prices']); ++$n) |
---|
| 208 | { |
---|
| 209 | $readonlys['project_prices['.(3+$n).'][pl_price]'] = |
---|
| 210 | $readonlys['project_prices['.(3+$n).'][pl_validsince]'] = true; |
---|
| 211 | } |
---|
| 212 | } |
---|
| 213 | $readonlys['button[save]'] = $readonlys['button[apply]'] = $view; |
---|
| 214 | $readonlys['button[edit]'] = !$view || !$this->check_acl(PHPGW_ACL_EDIT) && !$this->check_acl(PHPGW_ACL_EDIT,$this->pm_id); |
---|
| 215 | |
---|
| 216 | if (!$this->pm_id) // no project tab for the general pricelist |
---|
| 217 | { |
---|
| 218 | $readonlys[$tabs]['project'] = true; |
---|
| 219 | } |
---|
| 220 | // no general price tab, if there are none and no rights to edit the general pricelist |
---|
| 221 | if (!count($this->data['prices']) && !$this->check_acl(PHPGW_ACL_EDIT)) |
---|
| 222 | { |
---|
| 223 | $readonlys[$tabs]['price'] = true; |
---|
| 224 | } |
---|
| 225 | $GLOBALS['phpgw_info']['flags']['app_header'] = lang('projectmanager').' - '. |
---|
| 226 | ($view ? lang('View price') : ($pl_id ? lang('Edit price') : lang('Add price'))) . |
---|
| 227 | ($this->pm_id ? ': ' . $this->project->data['pm_number'] . ': ' .$this->project->data['pm_title'] : ''); |
---|
| 228 | |
---|
| 229 | //_debug_array($content); |
---|
| 230 | //_debug_array($readonlys); |
---|
| 231 | return $tpl->exec('projectmanager.uipricelist.edit',$content,array( |
---|
| 232 | 'pl_billable' => $this->billable_lables, |
---|
| 233 | ),$readonlys,$preserv,2); |
---|
| 234 | } |
---|
| 235 | |
---|
| 236 | /** |
---|
| 237 | * query pricelist for nextmatch |
---|
| 238 | * |
---|
| 239 | * reimplemented from so_sql to disable action-buttons based on the acl and make some modification on the data |
---|
| 240 | * |
---|
| 241 | * @param array $query |
---|
| 242 | * @param array &$rows returned rows/cups |
---|
| 243 | * @param array &$readonlys eg. to disable buttons based on acl |
---|
| 244 | */ |
---|
| 245 | function get_rows(&$query,&$rows,&$readonlys) |
---|
| 246 | { |
---|
| 247 | $GLOBALS['phpgw']->session->appsession('pricelist','projectmanager',$query); |
---|
| 248 | |
---|
| 249 | if ($query['cat_id']) |
---|
| 250 | { |
---|
| 251 | $query['col_filter']['cat_id'] = $query['cat_id']; |
---|
| 252 | } |
---|
| 253 | if ($query['col_filter']['pm_id'] === '' || !$this->check_acl(PHPGW_ACL_READ,$query['col_filter']['pm_id'])) |
---|
| 254 | { |
---|
| 255 | unset($query['col_filter']['pm_id']); |
---|
| 256 | } |
---|
| 257 | elseif ($query['col_filter']['pm_id'] != $this->pm_id) |
---|
| 258 | { |
---|
| 259 | $this->uipricelist($query['col_filter']['pm_id']); |
---|
| 260 | } |
---|
| 261 | if ($query['col_filter']['pl_billable'] === '') unset($query['col_filter']['pl_billable']); |
---|
| 262 | |
---|
| 263 | $total = parent::get_rows($query,$rows,$readonlys,true); |
---|
| 264 | |
---|
| 265 | $readonlys = array(); |
---|
| 266 | foreach($rows as $n => $val) |
---|
| 267 | { |
---|
| 268 | $row =& $rows[$n]; |
---|
| 269 | if (!$this->check_acl(PHPGW_ACL_EDIT) && !($this->pm_id && $this->check_acl(PHPGW_ACL_EDIT,$this->pm_id))) |
---|
| 270 | { |
---|
| 271 | $readonlys["edit[$row[pl_id]]"] = true; |
---|
| 272 | } |
---|
| 273 | // we only delete prices from the shown pricelist, not inhirited ones or onces from the general list |
---|
| 274 | if ($row['pm_id'] != $this->pm_id || !$this->check_acl(PHPGW_ACL_EDIT,$this->pm_id)) |
---|
| 275 | { |
---|
| 276 | $readonlys["delete[$row[pm_id]:$row[pl_id]]"] = true; |
---|
| 277 | } |
---|
| 278 | } |
---|
| 279 | $rows['standard_only'] = !$this->pm_id; |
---|
| 280 | |
---|
| 281 | return $total; |
---|
| 282 | } |
---|
| 283 | |
---|
| 284 | function index($content=null,$msg='') |
---|
| 285 | { |
---|
| 286 | while (!$this->check_acl(PHPGW_ACL_READ,$this->pm_id)) |
---|
| 287 | { |
---|
| 288 | if ($this->pm_id) // try falling back to the general pricelist |
---|
| 289 | { |
---|
| 290 | $GLOBALS['phpgw']->session->appsession('pm_id','projectmanager',$_REQUEST['pm_id'] = $this->pm_id = 0); |
---|
| 291 | } |
---|
| 292 | else |
---|
| 293 | { |
---|
| 294 | $GLOBALS['phpgw']->redirect_link('/index.php',array( |
---|
| 295 | 'menuaction' => 'projectmanager.uiprojectmanager.index', |
---|
| 296 | 'msg' => lang('Permission denied !!!'), |
---|
| 297 | )); |
---|
| 298 | } |
---|
| 299 | } |
---|
| 300 | $tpl =& new etemplate('projectmanager.pricelist.list'); |
---|
| 301 | |
---|
| 302 | if (!is_array($content)) |
---|
| 303 | { |
---|
| 304 | $content = array(); |
---|
| 305 | } |
---|
| 306 | elseif($content['nm']['rows']['delete']) |
---|
| 307 | { |
---|
| 308 | list($id) = @each($content['nm']['rows']['delete']); |
---|
| 309 | list($pm_id,$pl_id) = explode(':',$id); |
---|
| 310 | |
---|
| 311 | if ($pl_id && $this->delete(array('pm_id' => $pm_id,'pl_id' => $pl_id))) |
---|
| 312 | { |
---|
| 313 | $msg = lang('Price deleted'); |
---|
| 314 | } |
---|
| 315 | else |
---|
| 316 | { |
---|
| 317 | $msg = lang('Permission denied !!!'); |
---|
| 318 | } |
---|
| 319 | } |
---|
| 320 | $content['msg'] = $msg ? $msg : $_GET['msg']; |
---|
| 321 | $content['nm'] = $GLOBALS['phpgw']->session->appsession('pricelist','projectmanager'); |
---|
| 322 | if (!is_array($content['nm'])) |
---|
| 323 | { |
---|
| 324 | $content['nm'] = array( |
---|
| 325 | 'get_rows' => 'projectmanager.uipricelist.get_rows', |
---|
| 326 | 'no_filter' => true, |
---|
| 327 | 'no_filter2' => true, |
---|
| 328 | 'order' => 'pl_title',// IO name of the column to sort after (optional for the sortheaders) |
---|
| 329 | 'sort' => 'DESC',// IO direction of the sort: 'ASC' or 'DESC' |
---|
| 330 | ); |
---|
| 331 | } |
---|
| 332 | $content['nm']['col_filter']['pm_id'] = $this->pm_id; |
---|
| 333 | |
---|
| 334 | $GLOBALS['phpgw_info']['flags']['app_header'] = lang('projectmanager').' - '.($this->pm_id ? |
---|
| 335 | lang('Pricelist') .': ' . $this->project->data['pm_number'] . ': ' .$this->project->data['pm_title'] : |
---|
| 336 | lang('General pricelist')); |
---|
| 337 | |
---|
| 338 | $projects = array(); |
---|
| 339 | foreach((array)$this->project->search(array( |
---|
| 340 | 'pm_status' => 'active', |
---|
| 341 | 'pm_id' => $this->pm_id, // active or the current one |
---|
| 342 | ),$this->project->table_name.'.pm_id AS pm_id,pm_number,pm_title','pm_number','','',False,'OR',false,array('pm_accounting_type' => 'pricelist')) as $project) |
---|
| 343 | { |
---|
| 344 | $projects[$project['pm_id']] = $project['pm_number'].': '.$project['pm_title']; |
---|
| 345 | } |
---|
| 346 | $projects[0] = lang('General pricelist'); |
---|
| 347 | |
---|
| 348 | $readonlys = array( |
---|
| 349 | // show add button only, if user has rights to add a new price |
---|
| 350 | 'add' => !$this->check_acl(PHPGW_ACL_EDIT,$this->pm_id), |
---|
| 351 | ); |
---|
| 352 | return $tpl->exec('projectmanager.uipricelist.index',$content,array( |
---|
| 353 | 'pl_billable' => $this->billable_lables, |
---|
| 354 | 'pm_id' => $projects, |
---|
| 355 | ),$readonlys); |
---|
| 356 | } |
---|
| 357 | } |
---|