/[drupal]/contributions/modules/carbon/carbon_crag.inc
ViewVC logotype

Contents of /contributions/modules/carbon/carbon_crag.inc

Parent Directory Parent Directory | Revision Log Revision Log | View Revision Graph Revision Graph


Revision 1.7 - (show annotations) (download) (as text)
Sat May 2 09:33:45 2009 UTC (6 months, 3 weeks ago) by johnackers
Branch: MAIN
CVS Tags: DRUPAL-6--1-0, HEAD
Changes since 1.6: +66 -5 lines
File MIME type: text/x-php
This is work in progress but committing because it doesn't statically include carbon_transfer.inc.
1 <?php
2 /**
3 * $Id$
4 *
5 * Drupal carbon CRAG module
6 *
7 * Created on 17-May-2007
8 *
9 * @file
10 *
11 * Provides the settlement reports that are unique to the Carbon
12 * Rationing Action Groups http://www.carbonrationing.org.uk.
13 *
14 * The file is included by carbon_report_page
15 *
16 * The functions in this file are not used or required for
17 * general use of the carbon module.
18 *
19 */
20
21
22 class CarbonCrag
23 {
24 var $header = null ;
25 var $sampleRecord = null ;
26 var $params = null ;
27
28 function initialize(&$params)
29 {
30 if (empty($params["cost"])) $params["cost"] = 0.05 ;
31 $this->params = $params ;
32 require_once(CARBON_PATH ."/carbon_transfer.inc"); // carbon purchases/sales (used by crags)
33 }
34
35 /**
36 * create column headers in array this->header
37 */
38
39 function initHeader()
40 {
41 $this->header = array(array(
42 "data" => t("account name"),"field" => "title","sort" => "asc"));
43 }
44
45 function writeOutput($map, $uid, $firstdate, $lastdate)
46 {
47 $target = $this->params["target"];
48
49 // for each item in the map, change the key and value to title and amount ;
50 $footprint_by_title = array();
51
52 $rows = array();
53 $debitCarbon = 0 ; $creditCarbon = 0 ;
54 $debitCash = 0 ; $debitCredit = 0 ;
55
56 $results = array();
57 foreach ($map as $nid => $account)
58 {
59 $stamps = carbon_stamp_array_load($nid, null, null);
60
61 $footprint = carbon_calculate_total($account, $stamps, $firstdate, $lastdate);
62
63 $results[] = $footprint;
64
65 $over = 0 ;
66 if (!empty($target))
67 {
68 $actual = sprintf("%.0f",$footprint->grand_co2);
69 $over = $actual - $target ;
70
71 if ($over > 0)
72 $debitCarbon += $over ;
73 else
74 $creditCarbon -= $over ;
75 }
76 }
77
78 if ($creditCarbon > $debitCarbon)
79 {
80 $creditPrice = $this->params["cost"]*$debitCarbon/$creditCarbon ;
81 }
82 else
83 {
84 $creditPrice = $this->params["cost"] ;
85 }
86 $debitPrice = $this->params["cost"] ; // debtors pay the same
87
88 $nummembers = 0 ;
89 $grouptotal = 0 ;
90 foreach ($results as $footprint)
91 {
92 $nummembers++ ;
93 $actual = sprintf("%.0f",$footprint->grand_co2);
94 $grouptotal += $footprint->grand_co2 ;
95 $under = $target - $actual ;
96 if ($under < 0)
97 {
98 $debitCash += $cash = $this->params["cost"] * $under ;
99 }
100 else
101 {
102 $creditCash -= $cash = $creditPrice * $under ;
103 }
104 $rows[] = array($footprint->account->account_link, $actual, $this->sign($under), $this->sign(sprintf("%.2f",$cash)));
105
106 }
107 $header = array(
108 array("data" => t("account name")),
109 array("data" => t("Emissions Kg")),
110 array("data" => t("Credit or Debit Kg")),
111 array("data" => t("Credit of Debit £"))
112 );
113 if ($nummembers == 0)
114 $comment = "No members" ;
115 else
116 $comment = t("Total emissions are !carbon-grand Kg. Average emissions per person are !carbon-average Kg." .
117 "</p><p>".
118 "Over emitters: the carbon price is set at !debit-carbon-price. ".
119 "The total carbon debt is !debit-carbon Kg. ".
120 "The total money to pay is !debit-cash. ".
121 "</p><p>".
122 "Under emitters: the carbon price is !credit-carbon-price. ".
123 "The total carbon credit is !credit-carbon Kg. ".
124 "If under emitters paid, total money that might be received: !credit-cash.",
125
126 array(
127 "!carbon-grand"=>sprintf("%.2f",$grouptotal),
128 "!carbon-average"=>sprintf("%.2f",$grouptotal/$nummembers),
129 "!credit-carbon"=>$creditCarbon,
130 "!credit-cash"=>sprintf("%.2f",$creditCash),
131 "!credit-carbon-price"=>sprintf("%.2f",$creditPrice),
132
133 "!debit-carbon"=>$debitCarbon,
134 "!debit-cash"=>sprintf("%.2f",$debitCash),
135 "!debit-carbon-price"=>sprintf("%.2f",$debitPrice)));
136
137 $daterange = _format_date_range($firstdate, $lastdate);
138 if (!empty($target))
139 {
140 $output .= "<p>Suggested CRAG Settlement for ". $daterange. ". Target is ".$target. "Kg CO2.</p>";
141 $output .= "<p>".$comment."</p>" ;
142 }
143 $output .= theme("table", $header, $rows);
144 return $output ;
145 }
146
147
148 function allocate(&$map, $uid, $org, $firstdate, $lastdate, $target, $carbonCost)
149 {
150 // calculate the footprints
151 foreach ($map as $nid => $footprint)
152 {
153 $t = new CarbonTransaction();
154 $t->initialize();
155 $t->title = "allocation" ;
156 $t->carbon = $target ;
157 $t->cost = null ;
158 $t->seller = 1 ; // admin
159 $t->buyer = $nid ; //
160 $t->valuedate = $lastdate ;
161 $transactions[] = $t ;
162 }
163 foreach ($transactions as $t)
164 {
165 $r = node_save($t);
166 drupal_set_message($t->toString($map), "info");
167 }
168 }
169
170 function deduct(&$map, $uid, $org, $firstdate, $lastdate, $target, $carbonCost)
171 {
172 // calculate the footprints
173 foreach ($map as $nid => $account)
174 {
175 $stamps = carbon_stamp_array_load($nid, null, null);
176 $footprints[$account->nid] = carbon_calculate_total($account, $stamps, $firstdate, $lastdate);
177
178 $t->initialize();
179 $t->title = "deduct" ;
180 $t->carbon = - $footprints[$account->nid];
181 $t->cost = null ;
182 $t->seller = 1 ; // admin
183 $t->buyer = $nid ; //
184 $t->valuedate = $lastdate ;
185 $transactions[] = $t ;
186 }
187 foreach ($transactions as $t)
188 {
189 $r = node_save($t);
190 drupal_set_message($t->toString($map), "info");
191 }
192 }
193
194 /**
195 * execute settlement by
196 * 1. adding quota to account at start period.
197 * 2. settle carbon amongst CRAG members
198 *
199 * @param key-value map of account number/footprint
200 * @param unknown_type $org
201 */
202
203 function settle(&$map, $uid, $org, $firstdate, $lastdate, $target, $carbonCost)
204 {
205 $footprints = array();
206
207 // calculate the footprints
208 foreach ($map as $nid => $account)
209 {
210 $stamps = carbon_stamp_array_load($nid, null, null);
211 $footprints[$account->nid] = carbon_calculate_total($account, $stamps, $firstdate, $lastdate);
212 }
213 $debitCarbon = 0 ; $creditCarbon = 0 ;
214 $debitCash = 0 ; $debitCredit = 0 ;
215
216
217 if (empty($target))
218 return ;
219
220 $numMembers = 0 ;
221 $creditors = array() ;
222 $debtors = array() ;
223
224 foreach ($footprints as $nid => $f)
225 {
226 $numMembers++ ;
227 $actual = $f->grand_co2;
228 $f->CO2_above_target = $actual - $target ;
229
230 if ($f->CO2_above_target > 0)
231 {
232 $debitCarbon += $f->CO2_above_target;
233 $debtors[$nid] = $f->CO2_above_target ;
234 }
235 if ($f->CO2_above_target < 0)
236 {
237 $creditCarbon -= $f->CO2_above_target;
238 $creditors[$nid] = -$f->CO2_above_target ;
239 }
240 }
241
242 if (count($creditors) >= $numMembers)
243 {
244 drupal_set_message("All accounts in credit, no settlement required.");
245 return ;
246 }
247
248 if (count($debtors) >= $numMembers)
249 {
250 drupal_set_message("All accounts in debit, settlement not possible.");
251 return ;
252 }
253
254 /*
255 *
256 p(. If total debts is greater than total credits (i.e. there are enough surplus units and the group has come in under target)
257
258 p((. number of credits that each CRAGger in debt must purchase from ever other CRAGger [1..n] if the CRAGger is in credit
259
260 p(((. = size of debt * number of credits held by CRAGger [1..n] in credit / total credits
261
262 p(. else (the group has missed its target)
263
264 p((. number of credits that each CRAGger in debt must purchase from every other CRAGger [1..n] if s/he is in credit
265
266 p(((. = size of debt * number of credits held by CRAGger [1..n] / total debts
267
268 CRAGger [1..n] represents all the other members of the CRAG.
269
270 */
271 $group_met_target = $creditCarbon < $debitCarbon ;
272 $total_purchase = 0 ;
273 $transactions = array();
274 foreach ($debtors as $did => $d)
275 {
276 // go to each account with carbon credit and purchase carbon
277 foreach ($creditors as $cid => $c)
278 {
279 if ($group_met_target)
280 $purchase = $footprints[$did]->CO2_above_target * -$footprints[$cid]->CO2_above_target / $debitCarbon ;
281 else
282 $purchase = $footprints[$did]->CO2_above_target * -$footprints[$cid]->CO2_above_target / $creditCarbon ;
283
284 $debtors[$did] -= $purchase ;
285 $creditors[$cid] -= $purchase ;
286 $total_purchase += $purchase ;
287 $t = new CarbonTransaction();
288 $t->initialize();
289 $t->title = "settlement" ;
290 $t->carbon = $purchase ;
291 $t->cost = $purchase * $carbonCost ;
292 $t->seller = $cid ; // creditors account id
293 $t->buyer = $did ; // debtors account id
294 $t->valuedate = $lastdate ;
295 $transactions[] = $t ;
296 }
297 }
298
299 // commit all the transactions as a batch
300
301 foreach ($transactions as $t)
302 {
303 $r = node_save($t);
304 drupal_set_message($t->toString($map), "info");
305 }
306 }
307
308 function setTitle($org, $user, $firstdate, $lastdate)
309 {
310 $title = empty($org) ? "" : "!org " ;
311 $title .= "CRAG settlement for !dates" ;
312 $daterange = _format_date_range($firstdate, $lastdate);
313 drupal_set_title(t($title, array("!org"=>$org, "!dates"=>_format_date_range($firstdate, $lastdate))));
314 }
315
316
317 function attachForm()
318 {
319 return "" ;
320 }
321
322 /**
323 * represent a signed number as a credit of debit as preferred by Jessica.
324 */
325
326 function sign($amount)
327 {
328 return $amount < 0 ? "D ".-$amount : "C ".$amount ;
329 }
330 }
331
332
333 /**
334 * this form allows the user to set the carbon price, target etc
335 * and then request the report that shows the calculations.
336 */
337
338
339 function carbon_crag_form($form_state, $default_params)
340 {
341 $path = drupal_get_path("module", "carbon");
342 drupal_add_css($path . "/carbon.css");
343
344 $form = array();
345
346 $form["select"] = array(
347 "#type" => "fieldset",
348 "#title" => "CRAG report selection",
349 "#collapsible" => FALSE,
350 "#collapsed" => FALSE);
351
352 $form["select"]["report"] = array(
353 "#type" => "hidden",
354 "#value" => "crag");
355
356 carbon_report_form_build($form["select"], $default_params, array("org", "firstdate", "period"));
357
358
359 $form["select"]["target"] = array(
360 "#type" => "textfield",
361 "#title" => t("target"),
362 "#description" => t("Kg of CO2"),
363 "#default_value" => $default_params["target"],
364 "#required" => FALSE,
365 "#size" => 12,
366 "#maxlength" => 40,
367 "#prefix"=> "<DIV class='float-left'>",
368 "#suffix"=> "</DIV>",
369 "#weight" => 3);
370
371 $form["select"]["cost"] = array(
372 "#type" => "textfield",
373 "#title" => t("cost of carbon"),
374 "#description" => t("£ per Kg"),
375 "#default_value" => $default_params["cost"],
376 "#required" => FALSE,
377 "#size" => 12,
378 "#maxlength" => 40,
379 "#prefix"=> "<DIV class='float-left'>",
380 "#suffix"=> "</DIV>",
381 "#weight" => 4);
382 /*
383 $form["select"]["allocate"] = array(
384 "#type" => "submit",
385 "#value" => t("allocate"),
386 "#prefix"=> "<DIV class='float-left'>",
387 "#suffix"=> "</DIV>",
388 "#weight" => 6);
389
390 $form["select"]["deduct"] = array(
391 "#type" => "submit",
392 "#value" => t("deduct"),
393 "#prefix"=> "<DIV class='float-left'>",
394 "#suffix"=> "</DIV>",
395 "#weight" => 7);
396 */
397 $form["select"]["submit"] = array(
398 "#type" => "submit",
399 "#value" => t("show settlement"),
400 "#prefix"=> "<DIV class='float-left'>",
401 "#suffix"=> "</DIV>",
402 "#weight" => 8);
403
404 $form["select"]["pay"] = array(
405 "#type" => "submit",
406 "#value" => t("pay settlement"),
407 "#prefix"=> "<DIV class='float-left'>",
408 "#suffix"=> "</DIV>",
409 "#weight" => 9);
410
411 return $form ;
412 }
413
414
415
416 function carbon_crag_form_submit(&$form, &$form_state)
417 {
418 $form_values = $form_state['values'];
419 if (isset($form_values["pay"]))
420 {
421 $op = ($form_values["op"]);
422 if ($op == t("pay settlement"))
423 {
424 _carbon_settle($form, $form_values);
425 drupal_set_message("Settlement processed", "info");
426 }
427 }
428 return carbon_report_form_submit($form, $form_state);
429 }
430
431 function _carbon_settle($form, $form_values)
432 {
433 global $user;
434 global $charts ; $charts = array(t("none"), t("bar"), t("pie"));
435 global $orgs ; // no idea where this is set
436
437 $params = _gather_form($form_values, array("report"=>"accounts", "firstdate"=>"20050101", "period"=>60, "org"=>"","chart"=>"pie",
438 "target"=> null, "cost"=> 0.05));
439
440 if (!empty($params["org"]))
441 $org = $orgs[$params["org"]]; // convert org_index into real name
442
443 $firstdate = CarbonDate::fromYYYYMMDD($params["firstdate"]);
444 $lastdate = _add_months($firstdate, $params["period"]);
445
446 // build a list of all known orgs (scaleable?)
447
448 $reporter = new CarbonCrag();
449 $reporter->initialize($params);
450
451 $map = carbon_report_base($uid, $org, $reporter->header);
452
453 $reporter->settle($map, $uid, $org, $firstdate, $lastdate, $params["target"], $params["cost"]);
454
455 drupal_goto("carbon/transfer");
456 }
457
458 ?>

  ViewVC Help
Powered by ViewVC 1.1.2