1
ostatkinadatu.php in trunk/web/include/reports – MultiMag

source: trunk/web/include/reports/ostatkinadatu.php @ 979

Last change on this file since 979 was 979, checked in by blacklight, 11 months ago
  • В отчёт *остатки тоавра на дату* добавлена группировка по производителю
File size: 11.3 KB
Line 
1<?php
2
3//      MultiMag v0.2 - Complex sales system
4//
5//      Copyright (C) 2005-2018, BlackLight, TND Team, http://tndproject.org
6//
7//      This program is free software: you can redistribute it and/or modify
8//      it under the terms of the GNU Affero General Public License as
9//      published by the Free Software Foundation, either version 3 of the
10//      License, or (at your option) any later version.
11//
12//      This program is distributed in the hope that it will be useful,
13//      but WITHOUT ANY WARRANTY; without even the implied warranty of
14//      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15//      GNU Affero General Public License for more details.
16//
17//      You should have received a copy of the GNU Affero General Public License
18//      along with this program.  If not, see <http://www.gnu.org/licenses/>.
19//
20
21/// Остатки товара на складе на выбранную дату
22class Report_OstatkiNaDatu extends BaseGSReport {
23   
24    protected $group_filter;
25    protected $col_cfg;
26    protected $orders = [
27            'name' => 'По наименованию',
28            'code' => 'По коду производителя',
29            'base_price' => 'По базовой цене',
30        ];
31   
32    function getName($short = 0) {
33        if ($short) {
34            return "Остатки на выбранную дату";
35        } else {
36            return "Остатки товара на складе на выбранную дату";
37        }
38    }
39
40    function Form() {
41        global $tmpl, $db;
42        $curdate = date("Y-m-d");
43        $def_order = \cfg::get('doc', 'sklad_default_order');
44        if($def_order == 'vc') {
45            $def_order = 'code';
46        }
47        else if($def_order == 'cost') {
48            $def_order = 'base_price';
49        }
50       
51        $tmpl->addContent("<h1>" . $this->getName() . "</h1>");
52        $tmpl->addContent("
53            <script type=\"text/javascript\">
54            addEventListener('load', function() {initCalendar('dt',false);},false);
55            </script>
56            <form action='' method='post'>
57            <input type='hidden' name='mode' value='ostatkinadatu'>
58            Дата:<br>
59            <input type='text' name='date' id='dt' value='$curdate'><br>
60            ");
61        $ldo = new \Models\LDO\skladnames();
62        $store_names = $ldo->getData();       
63        $tmpl->addContent("Склад:<br>". \widgets::getEscapedSelect('store', $store_names) ."<br>" );
64        $tmpl->addContent("Сортировка:<br>". \widgets::getEscapedSelect('order', $this->orders, $def_order) ."<br>" );
65        $tmpl->addContent("Группа товаров:<br>");
66        $this->GroupSelBlock();
67        $tmpl->addContent("<label><input type='checkbox' name='group_vendor' value='1'>Группировать по производителю</labe><br>
68            Формат: <select name='opt'><option>pdf</option><option>html</option></select><br>           
69            <button type='submit'>Создать отчет</button></form>");
70    }
71   
72    protected function setColumn($id, $name, $width, $flexible = false) {
73        $this->col_cfg[$id] = [
74            'name' => $name,
75            'width' => $width,
76            'flex' => $flexible,
77            'hidden' => false,
78        ];
79    }
80   
81    protected function fixColumnWidth($all_width = 100) {
82        $sum_width_flex = $sum_width_noflex = 0;
83        $flex = [];
84        foreach($this->col_cfg as $id => $col) {
85            if($col['hidden']) {
86                continue;
87            }
88            if($col['flex']) {
89                $sum_width_flex += $col['width'];
90                $flex[] = $id;
91            }
92            else {
93                $sum_width_noflex += $col['width'];
94            }
95        }
96        $all_sum = $sum_width_noflex + $sum_width_flex;
97        if($all_width == $all_sum) {
98            return;
99        }
100        else {
101            $flex_mod = ($all_width - $sum_width_noflex) / $sum_width_flex;
102            foreach($this->col_cfg as $id => $col) {
103                if($col['flex']) {
104                    $this->col_cfg[$id]['width'] *= $flex_mod;
105                }
106            }
107        }   
108       
109    }
110   
111    protected function groupsMakeTable($options) {
112        global $db;
113        $c_count = 0;
114        foreach($this->col_cfg as $col) {
115            if(!$col['hidden']) {
116                $c_count++;
117            }
118        } 
119        switch ($options['order']) {
120            case 'code': 
121                $order = '`doc_base`.`vc`';
122                break;
123            case 'base_price': 
124                $order = '`doc_base`.`cost`';
125                break;
126            default: 
127                $order = '`doc_base`.`name`';
128        }
129       
130        $res_group = $db->query("SELECT `id`, `name` FROM `doc_group` ORDER BY `id`");
131        while ($group_line = $res_group->fetch_assoc()) {
132            if ($this->group_filter && !in_array($group_line['id'], $this->group_filter)) {
133                continue;
134            }
135
136            $this->tableAltStyle();
137            $this->tableSpannedRow(array($c_count), array(html_out("{$group_line['id']}. {$group_line['name']}")));
138            $this->tableAltStyle(false);
139
140            $res = $db->query("SELECT `doc_base`.`id`, CONCAT(`doc_base`.`name`, ' - ', `doc_base`.`proizv`) AS `name` , `doc_base`.`cost`,
141                    `doc_base`.`mass`, `doc_base`.`vc`
142                FROM `doc_base`
143                WHERE `doc_base`.`group`='{$group_line['id']}'
144                ORDER BY $order");
145            while ($nxt = $res->fetch_row()) {
146                $count = getStoreCntOnDate($nxt[0], $options['store_id'], $this->time, 1);
147                if ($count == 0) {
148                    continue;
149                }
150                if ($count < 0) {
151                    $this->zeroflag = 1;
152                }
153                $cost_p = sprintf("%0.2f", $nxt[2]);
154                $bsum_p = sprintf("%0.2f", $nxt[2] * $count);
155                $count_p = round($count, 3);
156                $this->bsum+=$nxt[2] * $count;
157                $this->summass+=$count * $nxt[3];
158
159                if (!$this->col_cfg['code']['hidden']) {
160                    $a = array($nxt[0], $nxt[4], $nxt[1], $count_p, $cost_p, $count * $nxt[3], $bsum_p);
161                } else {
162                    $a = array($nxt[0], $nxt[1], $count_p, $cost_p, $count * $nxt[3], $bsum_p);
163                }
164                $this->tableRow($a);
165            }
166        }
167    }
168   
169    protected function tableSort($a, $b) {
170        return strcmp($a['name'], $b['name']);
171    }
172
173    protected function vendorMakeTable($options) {
174        global $db;
175        $c_count = 0;
176        foreach($this->col_cfg as $col) {
177            if(!$col['hidden']) {
178                $c_count++;
179            }
180        } 
181        $res = $db->query("SELECT `doc_base`.`id`, `doc_base`.`proizv` AS `name` , `doc_base`.`cost` AS `base_price`,
182                `doc_base`.`mass`
183            FROM `doc_base`");
184        $data = [];
185        while ($line = $res->fetch_assoc()) {
186            $id = $line['name'];
187            /*if($id === null) {
188                continue;
189            }*/
190            $count = getStoreCntOnDate($line['id'], $options['store_id'], $this->time, 1);
191            if ($count == 0) {
192                continue;
193            }
194            if ($count < 0) {
195                $this->zeroflag = 1;
196            }
197           
198            if(!isset($data[$id])) {
199                $data[$id] = [
200                    'name' => $id,
201                    'mass' => 0,
202                    'count' => 0,
203                    'sum' => 0,
204                ];
205            }
206            $data[$id]['count'] += $count;
207            $data[$id]['mass'] += $count * $line['mass'];
208            $data[$id]['sum'] += $count * $line['base_price'];
209        }
210       
211        uasort($data, [$this, 'tableSort']);
212       
213        foreach($data as $line) {           
214            $sum_p = sprintf("%0.2f", $line['sum']);
215            $count_p = round($line['count'], 3);
216            $this->bsum += $line['sum'];
217            $this->summass += $line['mass'];
218            $a = array($line['name'], $count_p, $line['mass'], $sum_p);
219            $this->tableRow($a);
220        }
221       
222    }
223           
224    function Make($engine) {
225        global $db, $CONFIG;
226        $store = rcvint('store');
227        $date = rcvdate('date');       
228        $gs = request('gs');
229        $g = request('g');
230        $group_vendor = rcvint('group_vendor');
231        $order = request('order');
232       
233        // Prepare options
234        $this->time = strtotime($date . " 23:59:59");       
235        if(!in_array($order, $this->orders)) {
236            $order = 'name';
237        }
238        $this->group_filter = false;
239        if($g && is_array($gs)) {
240            $this->group_filter = $gs;
241        }       
242       
243        $res = $db->query("SELECT `name` FROM `doc_sklady` WHERE `id`='$store'");
244        if (!$res->num_rows) {
245            throw new \Exception("Склад не найден!");
246        }
247        list($sklad_name) = $res->fetch_row();
248
249        $this->loadEngine($engine);
250       
251        $this->setColumn('id', 'N', 7);
252        $this->setColumn('code', 'Код', 7);
253        $this->setColumn('name', 'Наименование', 60, true);
254        $this->setColumn('count', 'Кол-во', 9);
255        $this->setColumn('base_price', 'Б. цена', 9);
256        $this->setColumn('mass', 'Масса', 9);
257        $this->setColumn('sum', 'Сумма', 9);       
258       
259        $this->col_cfg['code']['hidden'] = !\cfg::get('poseditor', 'vc');
260       
261        $h_text = "Остатки товара на складе N$store ($sklad_name) на дату ".date("Y-m-d", $this->time);
262        if($group_vendor) {
263            $h_text .= ", сгруппированный по производителю";
264            $this->col_cfg['id']['hidden'] = true;
265            $this->col_cfg['code']['hidden'] = true;
266            $this->col_cfg['base_price']['hidden'] = true;
267            $this->col_cfg['name']['name'] = 'Производитель';
268        }
269        $this->header($h_text);
270       
271        $this->fixColumnWidth();
272       
273        $c_widths = [];
274        $c_captions = [];
275        $c_count = 0;
276        foreach($this->col_cfg as $col) {
277            if(!$col['hidden']) {
278                $c_widths[] = $col['width'];
279                $c_captions[] = $col['name'];
280                $c_count++;
281            }
282        } 
283        $this->tableBegin($c_widths);
284        $this->tableHeader($c_captions);
285
286        $this->zeroflag = $this->bsum = $this->summass = 0;
287        if($group_vendor) {
288            $this->vendorMakeTable( [
289                'order' => $order,
290                'store_id' => $store,
291            ]);
292        }
293        else {
294            $this->groupsMakeTable( [
295                'order' => $order,
296                'store_id' => $store,
297            ]);
298        }
299       
300        $this->bsum = sprintf("%0.2f", $this->bsum);
301        $this->tableAltStyle();
302        $this->tableSpannedRow(array($c_count - 1, 1), array('Итого:', $this->bsum));
303        if (!$this->zeroflag) {
304            $this->tableSpannedRow(array($c_count), array("Общая масса склада: $this->summass кг."));
305        } else {
306            $this->tableSpannedRow(array($c_count), array("Общая масса склада: невозможно определить из-за отрицательных остатков"));
307        }
308        $this->tableAltStyle(false);
309        $this->tableEnd();
310        $this->output();
311        exit(0);
312    }
313
314}
Note: See TracBrowser for help on using the repository browser.