Overview
  • Namespace
  • Class

Namespaces

  • rpf
    • api
      • module
    • extension
      • module
    • system
      • module

Classes

  • rpf\api\api
  • rpf\api\apiModule
  • rpf\api\bbRpc
  • rpf\api\module\bbCustomer_getFreeOrdNr
  • rpf\api\module\bbCustomer_readAddress
  • rpf\api\module\bbCustomer_readDiscount
  • rpf\api\module\bbCustomer_readEntry
  • rpf\api\module\bbCustomer_readPayment
  • rpf\api\module\bbCustomer_readTitle
  • rpf\api\module\bbCustomer_saveAdress
  • rpf\api\module\bbCustomer_validateAddress
  • rpf\api\module\bbCustomer_validateEntry
  • rpf\api\module\bbCustomer_validatePayinfo
  • rpf\api\module\bbDomain_readEntry
  • rpf\api\module\bbDomain_readFrontpage
  • rpf\api\module\bbDomain_readHandles
  • rpf\api\module\bbDomain_readPhpini
  • rpf\api\module\bbDomain_readSettings
  • rpf\api\module\bbDomain_readSubdomain
  • rpf\api\module\bbDomain_readWebalizerSettings
  • rpf\api\module\bbDomain_searchEntry
  • rpf\api\module\bbEmail_readAccount
  • rpf\api\module\bbMysql_inuseEntry
  • rpf\api\module\bbMysql_makeBackup
  • rpf\api\module\bbMysql_readEntry
  • rpf\api\module\bbOrder_readAccountAddress
  • rpf\api\module\bbOrder_readAccountEntry
  • rpf\api\module\bbOrder_readDisposition
  • rpf\api\module\bbOrder_readEntry
  • rpf\api\module\bbQuota_readEntry
  • rpf\api\module\customer
  • rpf\api\module\email
  • rpf\api\module\order
  • rpf\api\module\placeholder
  • rpf\api\module\user
  • rpf\extension\extension
  • rpf\extension\extensionModule
  • rpf\extension\invoiceTextExport
  • rpf\extension\mailExport
  • rpf\extension\module\domainExport
  • rpf\extension\module\index
  • rpf\extension\module\mgntRatioExport
  • rpf\system\module
  • rpf\system\module\log
  • rpf\system\module\moduleManager
  • rpf\system\rpf

Exceptions

  • rpf\system\module\exception
  1 <?php
  2 
  3 namespace rpf\extension\module;
  4 
  5 /**
  6  * class mgntRatioExport
  7  *
  8  * Calculates the contribution margin 1 - 5 of all products managed in the rp2.
  9  * Supports CSV-Export and in future mysql-storage
 10  *
 11  * --------------------------------------------------------------------------------------------------------------------
 12  *
 13  * selling price
 14  * -  external costs
 15  * = cm1
 16  *
 17  * - personal costs
 18  * = cm2
 19  *
 20  * - overheads direct (server infrastructure, ...)
 21  * - overheads indirect (costs for other free-of-charge products)
 22  * = cm3
 23  *
 24  * x sales volume
 25  * - discounts
 26  * = CM4 (overall)
 27  *
 28  * - costs for unbilled products of this type
 29  * + indirect overhead-credit for unbilled products of this type
 30  * = CM5
 31  *
 32  * --------------------------------------------------------------------------------------------------------------------
 33  *
 34  * @author Andreas Doebeling <ad@1601.com>
 35  * @copyright 1601.production siegler&thuemmler ohg
 36  * @license cc-by-sa - http://creativecommons.org/licenses/by-sa/4.0/
 37  * @link https://www.xing.com/profile/Andreas_Doebeling/
 38  * @link https://github.com/ADoebeling
 39  *
 40  * @package system\extension
 41  *
 42  * @version 0.1.151021_dev_1ad
 43  */
 44 class mgntRatioExport extends extensionModule
 45 {
 46     /** @var array $purchasePrices all costs */
 47     protected $costs = array();
 48     
 49     /** @var array all sums */
 50     protected $sum = array();
 51 
 52     /** @var array all products */
 53     protected $product = array();
 54 
 55     /** @var array all total */
 56     protected $total = array();
 57 
 58     /**
 59      * Build the $data-array
 60      *
 61      * @param extension $system
 62      */
 63     public function __construct(extension &$system)
 64     {
 65         parent::__construct($system);
 66         $this->data['costs'] =& $this->costs;
 67         $this->data['sum'] =& $this->sum;
 68         $this->data['product'] =& $this->product;
 69         $this->data['total'] =& $this->total;
 70     }
 71     
 72     /**
 73      * Set purchase-prices
 74      *
 75      * @param array $costs [tariff|domain|add-on|ext][pronr][externalCosts|workingTime|systemPoints] = X
 76      * @return $this
 77      */
 78     public function setPurchasePrices(array $prices)
 79     {
 80         $this->costs = $prices;
 81         return $this;
 82     }
 83 
 84 
 85     /**
 86      * Adds the sum of count, turnover, systemPoints, ... and stores them to
 87      * $this->sum[$type][$name][turnoverRegular] = X
 88      *
 89      * @return $this
 90      */
 91     protected function calcOverall()
 92     {
 93         foreach ($this->system->orders->loadAll(['accounting' => 1])->getData() as $order)
 94         {
 95             foreach ($order['dispositions'] as $dispo)
 96             {
 97                 // Only count active orders
 98                 if ((strtotime($dispo['account_end']) != 0 && strtotime($dispo['account_end']) < time())) {
 99                     continue;
100                 }
101 
102                 $sum =& $this->sum[$dispo['product']['norm']][$dispo['product']['pronr']];
103 
104                 /** @var int $p['count'] amount of products */
105                 $sum['count'];
106 
107                 /** @var int $p['countBilled'] amount of products that can be billed directly */
108                 $sum['countBilled'];
109 
110                 /** @var int $p['countUnbilled'] amount of products that can't be billed directly */
111                 $sum['countUnbilled'];
112 
113                 /** @var float $sum['turnoverRegular'] Sum of all turnovers by default-price that could be billed directly*/
114                 $sum['turnoverRegular'];
115 
116                 /** @var float $sum['turnoverBilled'] Sum of all turnovers by real-price that can be billed directly */
117                 $sum['turnoverBilled'];
118 
119                 /** @var int $sum['systemPoints'] Sum of all taken system-points */
120                 $sum['systemPoints'];
121 
122                 /** @var int $sum['systemPointsBilled'] Sum of all taken system-points that can be billed directly */
123                 $sum['systemPointsBilled'];
124 
125                 /** @var int $sum['systemPointsUnbilled'] Sum of all taken system-points that can't be billed directly */
126                 $sum['systemPointsUnbilled'];
127 
128                 /** @var float $sum['externalCosts'] Sum of all external costs */
129                 $sum['externalCosts'];
130 
131                 /** @var float $sum['externalCostsBilled'] Sum of all external costs that can be billed directly */
132                 $sum['externalCostsBilled'];
133 
134                 /** @var float $sum['externalCostsUnbilled'] Sum of all external costs that can't be billed directly */
135                 $sum['externalCostsUnbilled'];
136 
137                 /** @var float $sum['workingTime'] Sum of all taken working-time in hours */
138                 $sum['workingTime'];
139 
140                 /** @var float $sum['workingTimeBilled'] Sum of all taken working-time in hours that can be billed directly */
141                 $sum['workingTimeBilled'];
142 
143                 /** @var float $sum['workingTimeUnbilled'] Sum of all taken working-time in hours that can't be billed directly */
144                 $sum['workingTimeUnbilled'];
145 
146                 /** @var float $sum['workingTime'] Sum of all taken working-time-costs */
147                 $sum['workingTimeCosts'];
148 
149                 /** @var float $sum['workingTimeBilled'] Sum of all taken working-time-costs that can be billed directly */
150                 $sum['workingTimeCostsBilled'];
151 
152                 /** @var float $sum['workingTimeUnbilled'] Sum of all taken working-time-costs that can be billed directly */
153                 $sum['workingTimeCostsUnbilled'];
154 
155                 /** @var array all orders */
156                 $sum['orders'][$order['ordnr']] += 1;
157 
158 
159                 // External Costs can be stored at the product or at the product-group
160                 if (isset($this->costs[$dispo['product']['norm']][$dispo['product']['pronr']]['externalCosts']))
161                 {
162                     $externalCosts = $this->costs[$dispo['product']['norm']][$dispo['product']['pronr']]['externalCosts'] * $dispo['amount'];
163                 }
164                 else if (isset($this->costs[$dispo['product']['norm']]['externalCosts']))
165                 {
166                     $externalCosts = $this->costs[$dispo['product']['norm']]['externalCosts'] * $dispo['amount'];
167                 }
168                 else
169                 {
170                     $externalCosts = 0;
171                 }
172 
173                 // Working Time can be stored at the product or at the product-group
174                 if (isset($this->costs[$dispo['product']['norm']][$dispo['product']['pronr']]['workingTime']))
175                 {
176                     $workingTime = $this->costs[$dispo['product']['norm']][$dispo['product']['pronr']]['workingTime'] * $dispo['amount'];
177                 }
178                 else if (isset($this->costs[$dispo['product']['norm']]['workingTime']))
179                 {
180                     $workingTime = $this->costs[$dispo['product']['norm']]['workingTime'] * $dispo['amount'];
181                 }
182                 else
183                 {
184                     $workingTime = 0;
185                 }
186 
187                 /** @var array $purchasePrice TMP alias for $this->costs[$dispo['product']['norm']][$dispo['product']['pronr']] */
188                 $purchasePrice = isset($this->costs[$dispo['product']['norm']][$dispo['product']['pronr']]) ? $this->costs[$dispo['product']['norm']][$dispo['product']['pronr']] : 0;
189 
190                 $systemPoints = isset($purchasePrice['systemPoints']) ? $purchasePrice['systemPoints'] * $dispo['amount'] : 0;
191                 $workingTimeCosts = isset($this->costs['workingTimeCosts']) ? $this->costs['workingTimeCosts'] * $workingTime : 0;
192 
193 
194                 /*
195                  * Billed
196                  */
197                 if ($dispo['price']['default_net'] != 0) // + $dispo['price']['unit_net']
198                 {
199                     $sum['turnoverRegular'] += $dispo['price']['default_net'] * $dispo['amount'];
200                     $sum['turnoverBilled'] += $dispo['price']['unit_net'] * $dispo['amount'];
201 
202                     $sum['countBilled'] += $dispo['amount'];
203                     $sum['systemPointsBilled'] += $systemPoints;
204                     $sum['externalCostsBilled'] += $externalCosts;
205                     $sum['workingTimeBilled'] += $workingTime;
206                     $sum['workingTimeCostsBilled'] += $workingTimeCosts;
207                 }
208 
209                 /*
210                  * Unbilled
211                  */
212                 else
213                 {
214                     $sum['countUnbilled'] += $dispo['amount'];
215                     $sum['systemPointsUnbilled'] += $systemPoints;
216                     $sum['externalCostsUnbilled'] += $externalCosts;
217                     $sum['workingTimeUnbilled'] += $workingTime;
218                     $sum['workingTimeCostsUnbilled'] += $workingTimeCosts;
219                 }
220 
221                 /*
222                  * Sums
223                  */
224                 $sum['count'] = $sum['countBilled'] + $sum['countUnbilled'];
225                 $sum['systemPoints'] = $sum['systemPointsBilled'] + $sum['systemPointsUnbilled'];
226                 $sum['externalCosts'] = $sum['externalCostsBilled'] + $sum['externalCostsUnbilled'];
227                 $sum['workingTime'] = $sum['workingTimeBilled'] + $sum['workingTimeUnbilled'];
228                 $sum['workingTimeCosts'] = $sum['workingTimeCostsBilled'] + $sum['workingTimeCostsUnbilled'];
229             }
230         }
231         return $this;
232     }
233 
234     /**
235      * Shares the overhead-costs to each product by systemPoints and stores them to
236      * $this->sum[$type][$name][overheadCosts|overheadCostsBilled|...] = X
237      *
238      * @return $this
239      * @throws \Exception
240      */
241     protected function calcOverallOverhead()
242     {
243         if (empty($this->sum)) throw new \Exception('$this->sum[] is empty. You have to run ::calcOverall first AND should have some active dispositions', 424);
244 
245         foreach ($this->sum as $type => &$products)
246         {
247             foreach ($products as $id => &$sum)
248             {
249                 /** @var float $sum[discount] */
250                 $sum['discount'] = $sum['turnoverRegular']-$sum['turnoverBilled'];
251 
252                 /** @var float $sum ['overhead'] Sum of all taken overhead-costs */
253                 $sum['overheadCosts'] = 0;
254 
255                 /** @var float $sum ['overheadBilled'] Sum of all taken overhead-costs that can be billed directly */
256                 $sum['overheadCostsBilled'] = 0;
257 
258                 /** @var float $sum ['overheadUnbilled'] Sum of all taken overhead-costs that can't be billed directly */
259                 $sum['overheadCostsUnbilled'] = 0;
260 
261                 if ($this->total['systemPoints'] > 0)
262                 {
263                     $sum['overheadCosts'] = $this->costs['overheadCosts'] / $this->total['systemPoints'] * $sum['systemPoints'];
264                     $sum['overheadCostsBilled'] = $this->costs['overheadCosts'] / $this->total['systemPointsBilled'] * $sum['systemPointsBilled'];
265                     $sum['overheadCostsUnbilled'] = $this->costs['overheadCosts'] / $this->total['systemPointsUnbilled'] * $sum['systemPointsUnbilled'];
266                 }
267 
268                 /** @var float $sum[unbilledCosts] */
269                 $sum['unbilledCosts'] = $sum['externalCostsUnbilled']+$sum['workingTimeCostsUnbilled']+$sum['overheadCostsUnbilled'];
270             }
271         }
272         return $this;
273     }
274 
275     /**
276      * Calculates the contribution-margin for all products and stores them to
277      * $this->sum[$type][$name][cmX] = Y
278      *
279      * @throws \Exception
280      * @return $this
281      */
282     protected function calcOverallContributionMargin()
283     {
284         if (empty($this->data['sum'])) throw new \Exception('$this->sum[] is empty. You have to run ::calcOverall first AND should have some active dispositions', 424);
285 
286         foreach ($this->data['sum'] as $type => &$products)
287         {
288             foreach ($products as $id => &$sum)
289             {
290                 if ($sum['turnoverRegular'] > 0)
291                 {
292                     $sum['unbilledCostsShare'] = $this->total['unbilledCosts'] / $this->total['systemPointsBilled'] * $sum['systemPointsBilled'];
293 
294                     $sum['cm1'] = $sum['turnoverRegular'] - $sum['externalCostsBilled'];
295                     $sum['cm2'] = $sum['cm1'] - $sum['workingTimeCostsBilled'];
296                     $sum['cm3'] = $sum['cm2'] - $sum['overheadCostsBilled'] - $sum['unbilledCostsShare'];
297                     $sum['cm4'] = $sum['cm3'] - $sum['discount'];
298                     $sum['cm5'] = $sum['cm4'];
299                     $sum['displayUnbilledCosts'] = $sum['unbilledCosts'];
300                     $sum['margin'] = 100/$sum['turnoverRegular']*$sum['cm3'];
301                 }
302                 else
303                 {
304                     $sum['cm1'] = $sum['turnoverRegular'] - $sum['externalCostsUnbilled'];
305                     $sum['cm2'] = $sum['cm1'] - $sum['workingTimeCostsUnbilled'];
306                     $sum['cm3'] = $sum['cm2'] - $sum['overheadCostsUnbilled'];
307                     $sum['cm4'] = $sum['cm3'] - $sum['discount'];
308                     $sum['cm5'] = $sum['cm4'] + $sum['unbilledCosts'];
309                     $sum['displayUnbilledCosts'] = 0;
310                     $sum['margin'] = 0;
311                 }
312                 $sum['displayUnbilledCredit'] = $sum['unbilledCosts'];
313             }
314         }
315         return $this;
316     }
317 
318     /**
319      * Calculates the benefits and costs for every single product based on $this->sum and stores them to
320      * $this->product[$type][$name][externalCosts|...] = X
321      *
322      * @return $this
323      * @throws \Exception
324      */
325     protected function calcProducts()
326     {
327         if (empty($this->sum)) throw new \Exception('$this->sum[] is empty. You have to run ::calcOverall first AND should have some active dispositions', 424);
328 
329         foreach ($this->sum as $type => &$products)
330         {
331             foreach ($products as $id => &$sum)
332             {
333                 $p =& $this->product[$type][$id];
334 
335                 /** @var string $p ['type'] type of the product */
336                 $p['type'] = $type;
337 
338                 /** @var string (!) $p ['id'] id of the product */
339                 $p['id'] = $id;
340 
341                 /** @var float $p ['externalCosts'] external product-costs */
342                 $p['externalCosts'] = 0;
343 
344                 /** @var float $p ['costsWorkingTime'] working-time-costs per product */
345                 $p['workingTimeCosts'] = 0;
346 
347                 /** @var int */
348                 $p['count'] = 0;
349 
350                 /** @var int */
351                 $p['countBilled'] = 0;
352 
353                 /** @var int */
354                 $p['countUnbilled'] = 0;
355 
356                 /** @var float $p ['turnoverRegular'] regular product-turnover */
357                 $p['turnoverRegular'] = 0;
358 
359                 /** @var float $p ['turnoverBilledAverage'] average product-turnover */
360                 $p['turnoverBilled'] = 0;
361 
362                 /** @var float $p ['externalCostsBilled'] billed external product-costs */
363                 $p['externalCosts'] = 0;
364 
365                 /** @var float $p ['workingTimeCostsBilled'] billed working-time-costs per product */
366                 $p['workingTimeCosts'] = 0;
367 
368                 /** @var float $p ['workingTime'] billed working-time per product */
369                 $p['workingTime'] = 0;
370 
371                 /** @var float $p ['costsOverheadBilled'] billed overhead-costs per product */
372                 $p['overheadCosts'] = 0;
373 
374                 $p['cm1'] = 0;
375                 $p['cm2'] = 0;
376                 $p['cm3'] = 0;
377                 $p['bestPrice'] = 0;
378 
379                 if ($sum['countBilled'] > 0)
380                 {
381                     $p['turnoverRegular'] =         $sum['turnoverRegular']          / $sum['countBilled'];
382                     $p['turnoverBilled'] =          $sum['turnoverBilled']           / $sum['countBilled'];
383                     $p['externalCosts'] =           $sum['externalCostsBilled']      / $sum['countBilled'];
384                     $p['workingTime'] =             $sum['workingTimeBilled']        / $sum['countBilled'];
385                     $p['workingTimeCosts'] =        $sum['workingTimeCostsBilled']   / $sum['countBilled'];
386                     $p['overheadCosts'] =           $sum['overheadCostsBilled']      / $sum['countBilled'];
387                     $p['unbilledCostsShare'] =      $sum['unbilledCostsShare']       / $sum['countBilled'];
388 
389                     $p['cm1'] =                     $sum['cm1']                      / $sum['countBilled'];
390                     $p['cm2'] =                     $sum['cm2']                      / $sum['countBilled'];
391                     $p['cm3'] =                     $sum['cm3']                      / $sum['countBilled'];
392                     
393                     $p['bestPrice'] = ($sum['externalCostsBilled']+$sum['workingTimeCostsBilled']+$sum['overheadCostsBilled']+$sum['unbilledCostsShare'])/$sum['countBilled']*1.15; // Every programmer loves magic numbers
394                 }
395                 else
396                 {
397                     $p['externalCosts'] =           $sum['externalCostsUnbilled']    / $sum['countUnbilled'];
398                     $p['workingTime'] =             $sum['workingTimeUnbilled']      / $sum['countUnbilled'];
399                     $p['workingTimeCosts']=         $sum['workingTimeCostsUnbilled'] / $sum['countUnbilled'];
400                     $p['overheadCosts'] =           $sum['overheadCostsUnbilled']    / $sum['countUnbilled'];
401                     $p['unbilledCosts'] =           $sum['unbilledCosts']            / $sum['countUnbilled'];
402 
403                     $p['cm1'] =                     $sum['cm1']                      / $sum['countUnbilled'];
404                     $p['cm2'] =                     $sum['cm2']                      / $sum['countUnbilled'];
405                     $p['cm3'] =                     $sum['cm3']                      / $sum['countUnbilled'];
406                     
407                     $p['bestPrice'] = ($sum['externalCostsUnbilled']+$sum['workingTimeCostsUnbilled']+$sum['overheadCostsUnbilled'])/$sum['countUnbilled']*1.15;
408                 }
409 
410                 foreach ($sum['orders'] as $ordnr => $count)
411                 {
412                     $p['orders'] .= "$ordnr({$count}x), ";
413                 }
414             }
415         }
416         return $this;
417     }
418 
419     /**
420      * Calc all total-sums for each category
421      *
422      * @return $this
423      */
424     protected function calcTotal()
425     {
426         $this->total = array(); // Never delete that line. I've searched this bug for hours
427 
428         foreach ($this->sum as $type => &$products)
429         {
430             foreach ($products as $name => &$product)
431             {
432                 foreach ($product as $key => &$val)
433                 {
434                     if (is_int($val) OR is_float($val))
435                     {
436                         $this->total[$key] += $val;
437                     }
438                 }
439             }
440         }
441         // Adding percent-values isn't so smart
442         $this->total['margin'] = $sum['margin'] = 100/$this->total['turnoverRegular']*$this->total['cm3'];
443         return $this;
444     }
445 
446 
447     /**
448      * Run all calculations in the right order:
449      * - calcOverall()
450      * - calcTotal()
451      * - calcOverallOverhead()
452      * - calcTotal()
453      * - calcOverallContributionMargin()
454      * - calcTotal()
455      * - calcProducts()
456      * - calcTotal
457      *
458      * Well, maybe you could optimize that, but I'm afraid u wouldn't get a relevant performance-enhancement
459      *
460      * @return $this
461      * @throws \Exception
462      */
463     public function calc()
464     {
465         $this->calcOverall();
466         $this->calcTotal();
467 
468         $this->calcOverallOverhead();
469         $this->calcTotal();
470 
471         $this->calcOverallContributionMargin();
472         $this->calcTotal();
473 
474         $this->calcProducts();
475         $this->calcTotal();
476 
477         return $this;
478     }
479 
480 
481     /**
482      * Returns a german export-csv
483      *
484      * @return string $csv
485      */
486     public function getCsvGe()
487     {
488         $csv =
489             'Produkttyp;'.
490             'Produktname;'.
491             'Anzahl;'.
492             ';'.
493 
494             '�-Listenpreis (Stk./Mon.);'.
495             ' - Fremdkosten;'.
496             'db1;'.
497             ';'.
498 
499             ' - Personalkosten (Mon.);'.
500             '(Personalaufwand/Jahr);'.
501             'db2;'.
502             ';'.
503 
504             ' - Gemeinkosten (Srv.-Infrastruktur, ...);'.
505             ' - Verrechnugsgemeinkosten (Inkl.-Domain, ...);'.
506             'db3;'.
507             'Marge (Listenpreis/db3);'.
508             ';'.
509 
510             'x verkaufter Anzahl;'.
511             ' - Rabatt;'.
512             'DB4;'.
513             ';'.
514 
515             ' - Verrechnungseinzelkosten;'.
516             ' + Verrechnungseinzelgutschrift;'.
517             'DB5;'.
518             ';'.
519 
520             'Niedrigstpreis (Kosten+15% / Stk./Mon.); '.
521             '�-Verkaufspreis (Stk./Mon.);'.
522             'Umsatz (Gesamt/Mon.); '.
523             ';'.
524 
525             'RP2-Auft�ge;'.
526             "\n\n";
527 
528         foreach ($this->data['product'] as $type => &$products)
529         {
530             ksort($products);
531             foreach ($products as $name => &$product)
532             {
533                 // Lil alias
534                 $sum =& $this->sum[$type][$name];
535                 $total =& $this->total;
536 
537                 $csv .= "$type;";
538                 $csv .= "$name;";
539                 $csv .= number_format($sum['count'], 0, ',', '.').';';
540                 $csv .= ';';
541 
542                 $csv .= self::getEuroFormattedCsvColumn($product['turnoverRegular']);
543                 $csv .= self::getEuroFormattedCsvColumn(-$product['externalCosts']);
544                 $csv .= self::getEuroFormattedCsvColumn($product['cm1']);
545                 $csv .= ';';
546 
547                 $csv .= self::getEuroFormattedCsvColumn(-$product['workingTimeCosts']);
548                 $csv .= date("H:i", mktime(0,0,0)+$product['workingTime']*60*60*12) .'; '; // mktime looks stupid here, but I needed hour 0
549                 $csv .= self::getEuroFormattedCsvColumn($product['cm2']);
550                 $csv .= ';';
551 
552                 $csv .= self::getEuroFormattedCsvColumn(-$product['overheadCosts']);
553                 $csv .= self::getEuroFormattedCsvColumn(-$product['unbilledCostsShare']);
554                 $csv .= self::getEuroFormattedCsvColumn($product['cm3']);
555                 $csv .= number_format($sum['margin'], 0, ',', '.').' %;';
556                 $csv .= ';';
557 
558                 $csv .= $sum['countBilled'].';';
559                 $csv .= self::getEuroFormattedCsvColumn(-$sum['discount']);
560                 $csv .= self::getEuroFormattedCsvColumn($sum['cm4']);
561                 $csv .= ';';
562 
563                 $csv .= self::getEuroFormattedCsvColumn(-$sum['displayUnbilledCosts']);
564                 $csv .= self::getEuroFormattedCsvColumn($sum['displayUnbilledCredit']);
565                 $csv .= self::getEuroFormattedCsvColumn($sum['cm5']);
566                 $csv .= ';';
567 
568 
569                 $csv .= self::getEuroFormattedCsvColumn($product['bestPrice']);
570                 $csv .= self::getEuroFormattedCsvColumn($product['turnoverBilled']);
571                 $csv .= self::getEuroFormattedCsvColumn($sum['turnoverRegular']);
572                 $csv .= ';';
573 
574                 $csv .= $product['orders'];
575                 $csv .= "\n";
576             }
577             $csv .= "\n";
578         }
579         
580         $csv .=
581             '**SUMME**;'.
582             ';'.
583             ';'.
584             ';'.
585 
586             self::getEuroFormattedCsvColumn($total['turnoverRegular']).
587             self::getEuroFormattedCsvColumn(-$total['externalCosts']).
588             self::getEuroFormattedCsvColumn($total['cm1']).
589             ';'.
590 
591             self::getEuroFormattedCsvColumn($total['workingTimeCosts']).
592             //date("d \M\T, H \h / \M\o\\\\n.", mktime(0,0,0)+$total['workingTime']*60*60).';'.
593             round($total['workingTime'],0).'h / Mon;'.
594             self::getEuroFormattedCsvColumn($total['cm2']).
595             ';'.
596 
597             self::getEuroFormattedCsvColumn(-$total['overheadCosts']).
598             self::getEuroFormattedCsvColumn(-$total['unbilledCostsShare']).
599             self::getEuroFormattedCsvColumn($total['cm3']).
600             number_format($total['margin'], 0, ',', '.').' %;'.
601             ';'.
602 
603             ';'.
604             self::getEuroFormattedCsvColumn(-$total['discount']).
605             self::getEuroFormattedCsvColumn($total['cm4']).
606             ';'.
607 
608             ';'.
609             ';'.
610             self::getEuroFormattedCsvColumn($total['cm5']).
611             ';'.
612 
613 
614             ';'.
615             self::getEuroFormattedCsvColumn($total['turnoverBilled']).
616             self::getEuroFormattedCsvColumn($total['turnoverRegular']);
617 
618         $csv .= "\n\n\n\nGenerated with mgntRatioExport: https://github.com/ADoebeling/RP2-Toolbox \nCopyright (C) 2015 by Andreas D�beling <ad@1601.com> - 1601.production, Siegler&Th�mmler ohg, Erlangen";
619 
620         return $csv;
621     }
622 
623     /**
624      * Returns given $float as "1.234,56 �;"
625      *
626      * @param $float
627      * @return string
628      */
629     public static function getEuroFormattedCsvColumn($float)
630     {
631         return number_format($float, 2, ',', '.').' �; ';
632     }
633 
634     /**
635      * Stores the calculated values to mysql
636      *
637      * @return $this
638      * @throws \Exception
639      * @todo Implement
640      */
641     public function store()
642     {
643         throw new \Exception("Sorry, not implemented yet", 501);
644         return $this;
645     }
646 
647 
648     /**
649      * Send application/csv-header and starts downloading the csv
650      *
651      * @param string $filename
652      * @param string $source
653      * @return $this
654      * @throws \Exception
655      */
656     public function sendDownloadCsv($filename = NULL, $source = 'ge')
657     {
658         $filename = $filename !== NULL ? $filename : 'Hosting_MgntRatioExport_'.date('ymd').'_1SRV.csv';
659 
660         if ($source == 'ge')
661         {
662             $csv = $this->getCsvGe();
663         }
664         else
665         {
666             throw new \Exception("Sorry, not implemented yet", 501);
667         }
668 
669         header('Content-Type: application/csv');
670         header("Content-Disposition: attachment; filename=\"$filename\";");
671         echo $csv;
672         return $this;
673     }
674 }
API documentation generated by ApiGen