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 | } |
---|