forked from Business/BinStack
		
	Add reports (close #7)
This commit is contained in:
		
							parent
							
								
									db72d8d38d
								
							
						
					
					
						commit
						98aa7d3217
					
				| @ -4,7 +4,9 @@ | ||||
|     "type": "project", | ||||
|     "require": { | ||||
|         "catfan/medoo": "^1.2", | ||||
|         "guzzlehttp/guzzle": "^6.2" | ||||
|         "guzzlehttp/guzzle": "^6.2", | ||||
|         "league/csv": "^9.0", | ||||
|         "lapinator/ods-php-generator": "^0.0.3" | ||||
|     }, | ||||
|     "license": "MPL-2.0", | ||||
|     "authors": [ | ||||
|  | ||||
							
								
								
									
										111
									
								
								composer.lock
									
									
									
										generated
									
									
									
								
							
							
						
						
									
										111
									
								
								composer.lock
									
									
									
										generated
									
									
									
								
							| @ -4,8 +4,8 @@ | ||||
|         "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file", | ||||
|         "This file is @generated automatically" | ||||
|     ], | ||||
|     "hash": "67e95c250946f032648f9527831ec71a", | ||||
|     "content-hash": "36bca807ff9018548a5ce6c686d131dc", | ||||
|     "hash": "0476ce3c9f1be7b4a13d6533df71433d", | ||||
|     "content-hash": "9ff412188d3e72a7961ecf9b9e966404", | ||||
|     "packages": [ | ||||
|         { | ||||
|             "name": "catfan/medoo", | ||||
| @ -247,6 +247,113 @@ | ||||
|             ], | ||||
|             "time": "2017-03-20 17:10:46" | ||||
|         }, | ||||
|         { | ||||
|             "name": "lapinator/ods-php-generator", | ||||
|             "version": "v0.0.3", | ||||
|             "source": { | ||||
|                 "type": "git", | ||||
|                 "url": "https://github.com/Lapinator/odsPhpGenerator.git", | ||||
|                 "reference": "575314c003c2ec3032813bedcc1d27032b7b7ab2" | ||||
|             }, | ||||
|             "dist": { | ||||
|                 "type": "zip", | ||||
|                 "url": "https://api.github.com/repos/Lapinator/odsPhpGenerator/zipball/575314c003c2ec3032813bedcc1d27032b7b7ab2", | ||||
|                 "reference": "575314c003c2ec3032813bedcc1d27032b7b7ab2", | ||||
|                 "shasum": "" | ||||
|             }, | ||||
|             "require": { | ||||
|                 "php": ">=5.3" | ||||
|             }, | ||||
|             "type": "library", | ||||
|             "autoload": { | ||||
|                 "classmap": [ | ||||
|                     "src/" | ||||
|                 ] | ||||
|             }, | ||||
|             "notification-url": "https://packagist.org/downloads/", | ||||
|             "license": [ | ||||
|                 "LGPL-3.0" | ||||
|             ], | ||||
|             "authors": [ | ||||
|                 { | ||||
|                     "name": "Laurent VUIBERT", | ||||
|                     "email": "lapinator@gmx.fr", | ||||
|                     "homepage": "http://lapinator.net", | ||||
|                     "role": "Developer" | ||||
|                 } | ||||
|             ], | ||||
|             "description": "Open Document Spreadsheet (.ods) generator ", | ||||
|             "homepage": "https://odsphpgenerator.lapinator.net/", | ||||
|             "keywords": [ | ||||
|                 "LibreOffice", | ||||
|                 "ods" | ||||
|             ], | ||||
|             "time": "2016-04-14 21:51:27" | ||||
|         }, | ||||
|         { | ||||
|             "name": "league/csv", | ||||
|             "version": "9.1.1", | ||||
|             "source": { | ||||
|                 "type": "git", | ||||
|                 "url": "https://github.com/thephpleague/csv.git", | ||||
|                 "reference": "66118f5c2a7e4da77e743e69f74773c63b73e8f9" | ||||
|             }, | ||||
|             "dist": { | ||||
|                 "type": "zip", | ||||
|                 "url": "https://api.github.com/repos/thephpleague/csv/zipball/66118f5c2a7e4da77e743e69f74773c63b73e8f9", | ||||
|                 "reference": "66118f5c2a7e4da77e743e69f74773c63b73e8f9", | ||||
|                 "shasum": "" | ||||
|             }, | ||||
|             "require": { | ||||
|                 "ext-mbstring": "*", | ||||
|                 "php": ">=7.0.10" | ||||
|             }, | ||||
|             "require-dev": { | ||||
|                 "ext-curl": "*", | ||||
|                 "friendsofphp/php-cs-fixer": "^2.0", | ||||
|                 "phpunit/phpunit": "^6.0" | ||||
|             }, | ||||
|             "suggest": { | ||||
|                 "ext-iconv": "Needed to ease transcoding CSV using iconv stream filters" | ||||
|             }, | ||||
|             "type": "library", | ||||
|             "extra": { | ||||
|                 "branch-alias": { | ||||
|                     "dev-master": "9.x-dev" | ||||
|                 } | ||||
|             }, | ||||
|             "autoload": { | ||||
|                 "psr-4": { | ||||
|                     "League\\Csv\\": "src" | ||||
|                 }, | ||||
|                 "files": [ | ||||
|                     "src/functions_include.php" | ||||
|                 ] | ||||
|             }, | ||||
|             "notification-url": "https://packagist.org/downloads/", | ||||
|             "license": [ | ||||
|                 "MIT" | ||||
|             ], | ||||
|             "authors": [ | ||||
|                 { | ||||
|                     "name": "Ignace Nyamagana Butera", | ||||
|                     "email": "nyamsprod@gmail.com", | ||||
|                     "homepage": "https://github.com/nyamsprod/", | ||||
|                     "role": "Developer" | ||||
|                 } | ||||
|             ], | ||||
|             "description": "Csv data manipulation made easy in PHP", | ||||
|             "homepage": "http://csv.thephpleague.com", | ||||
|             "keywords": [ | ||||
|                 "csv", | ||||
|                 "export", | ||||
|                 "filter", | ||||
|                 "import", | ||||
|                 "read", | ||||
|                 "write" | ||||
|             ], | ||||
|             "time": "2017-11-28 08:29:49" | ||||
|         }, | ||||
|         { | ||||
|             "name": "psr/http-message", | ||||
|             "version": "1.0.1", | ||||
|  | ||||
							
								
								
									
										
											BIN
										
									
								
								database.mwb
									
									
									
									
									
								
							
							
						
						
									
										
											BIN
										
									
								
								database.mwb
									
									
									
									
									
								
							
										
											Binary file not shown.
										
									
								
							
							
								
								
									
										14
									
								
								database.sql
									
									
									
									
									
								
							
							
						
						
									
										14
									
								
								database.sql
									
									
									
									
									
								
							| @ -1,5 +1,5 @@ | ||||
| -- MySQL Script generated by MySQL Workbench | ||||
| -- Tue 17 Oct 2017 03:17:47 AM MDT | ||||
| -- Tue 26 Dec 2017 04:44:44 PM MST | ||||
| -- Model: New Model    Version: 1.0 | ||||
| -- MySQL Workbench Forward Engineering | ||||
| 
 | ||||
| @ -102,6 +102,18 @@ CREATE TABLE IF NOT EXISTS `inventory`.`permissions` ( | ||||
| ENGINE = InnoDB; | ||||
| 
 | ||||
| 
 | ||||
| -- ----------------------------------------------------- | ||||
| -- Table `inventory`.`report_access_codes` | ||||
| -- ----------------------------------------------------- | ||||
| CREATE TABLE IF NOT EXISTS `inventory`.`report_access_codes` ( | ||||
|   `id` INT NOT NULL AUTO_INCREMENT, | ||||
|   `code` VARCHAR(45) NULL, | ||||
|   `expires` DATETIME NULL, | ||||
|   PRIMARY KEY (`id`), | ||||
|   UNIQUE INDEX `id_UNIQUE` (`id` ASC)) | ||||
| ENGINE = InnoDB; | ||||
| 
 | ||||
| 
 | ||||
| SET SQL_MODE=@OLD_SQL_MODE; | ||||
| SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS; | ||||
| SET UNIQUE_CHECKS=@OLD_UNIQUE_CHECKS; | ||||
|  | ||||
							
								
								
									
										13
									
								
								database_upgrade/v1.0.1_1.1.sql
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										13
									
								
								database_upgrade/v1.0.1_1.1.sql
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,13 @@ | ||||
| /*  | ||||
|  * This Source Code Form is subject to the terms of the Mozilla Public | ||||
|  * License, v. 2.0. If a copy of the MPL was not distributed with this | ||||
|  * file, You can obtain one at http://mozilla.org/MPL/2.0/. | ||||
|  */ | ||||
| CREATE TABLE IF NOT EXISTS `report_access_codes` ( | ||||
|   `id` INT(11) NOT NULL AUTO_INCREMENT, | ||||
|   `code` VARCHAR(45) NULL DEFAULT NULL, | ||||
|   `expires` DATETIME NULL DEFAULT NULL, | ||||
|   PRIMARY KEY (`id`), | ||||
|   UNIQUE INDEX `id_UNIQUE` (`id` ASC)) | ||||
| ENGINE = InnoDB | ||||
| DEFAULT CHARACTER SET = utf8 | ||||
| @ -95,5 +95,15 @@ define("STRINGS", [ | ||||
|     "missing name" => "You need to enter a name.", | ||||
|     "use the dropdowns" => "Whoops, you need to use the category and location autocomplete boxes.", | ||||
|     "make categories and locations" => "Please create at least one category and location before adding an item.", | ||||
|     "search" => "Search Items" | ||||
|     "search" => "Search Items", | ||||
|     "report export" => "Reports/Export", | ||||
|     "report type" => "Report type", | ||||
|     "format" => "Format", | ||||
|     "generate report" => "Generate report", | ||||
|     "choose an option" => "Choose an option", | ||||
|     "csv file" => "CSV text file", | ||||
|     "ods file" => "ODS spreadsheet", | ||||
|     "html file" => "HTML web page", | ||||
|     "itemid" => "Item ID", | ||||
|     "id" => "ID" | ||||
| ]); | ||||
							
								
								
									
										261
									
								
								lib/reports.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										261
									
								
								lib/reports.php
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,261 @@ | ||||
| <?php | ||||
| 
 | ||||
| /* This Source Code Form is subject to the terms of the Mozilla Public | ||||
|  * License, v. 2.0. If a copy of the MPL was not distributed with this | ||||
|  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ | ||||
| 
 | ||||
| 
 | ||||
| // Detect if loaded by the user or by PHP
 | ||||
| if (count(get_included_files()) == 1) { | ||||
|     define("LOADED", true); | ||||
| } else { | ||||
|     define("LOADED", false); | ||||
| } | ||||
| 
 | ||||
| require_once __DIR__ . "/../required.php"; | ||||
| 
 | ||||
| use League\Csv\Writer; | ||||
| use League\Csv\HTMLConverter; | ||||
| use odsPhpGenerator\ods; | ||||
| use odsPhpGenerator\odsTable; | ||||
| use odsPhpGenerator\odsTableRow; | ||||
| use odsPhpGenerator\odsTableColumn; | ||||
| use odsPhpGenerator\odsTableCellString; | ||||
| use odsPhpGenerator\odsStyleTableColumn; | ||||
| use odsPhpGenerator\odsStyleTableCell; | ||||
| 
 | ||||
| // Allow access with a download code, for mobile app and stuff
 | ||||
| $date = date("Y-m-d H:i:s"); | ||||
| if (isset($VARS['code']) && LOADED) { | ||||
|     if (!$database->has('report_access_codes', ["AND" => ['code' => $VARS['code'], 'expires[>]' => $date]])) { | ||||
|         dieifnotloggedin(); | ||||
|     } | ||||
| } else { | ||||
|     dieifnotloggedin(); | ||||
| } | ||||
| 
 | ||||
| // Delete old DB entries
 | ||||
| $database->delete('report_access_codes', ['expires[<=]' => $date]); | ||||
| 
 | ||||
| if (LOADED) { | ||||
|     if (isset($VARS['type']) && isset($VARS['format'])) { | ||||
|         generateReport($VARS['type'], $VARS['format']); | ||||
|         die(); | ||||
|     } else { | ||||
|         lang("invalid parameters"); | ||||
|         die(); | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| /** | ||||
|  * Get a 2d array of the items in the database. | ||||
|  * @global type $database | ||||
|  * @param array $filter Medoo WHERE clause. | ||||
|  * @return string | ||||
|  */ | ||||
| function getItemReport($filter = []) { | ||||
|     global $database; | ||||
|     $items = $database->select( | ||||
|             "items", [ | ||||
|         "[>]locations" => ["locid"], | ||||
|         "[>]categories" => ["catid"] | ||||
|             ], [ | ||||
|         "itemid", | ||||
|         "name", | ||||
|         "catname", | ||||
|         "locname", | ||||
|         "code1", | ||||
|         "code2", | ||||
|         "qty", | ||||
|         "want", | ||||
|         "userid", | ||||
|         "text1", | ||||
|         "text2", | ||||
|         "text3" | ||||
|             ], $filter | ||||
|     ); | ||||
|     $header = [ | ||||
|         lang("itemid", false), | ||||
|         lang("name", false), | ||||
|         lang("category", false), | ||||
|         lang("location", false), | ||||
|         lang("code 1", false), | ||||
|         lang("code 2", false), | ||||
|         lang("quantity", false), | ||||
|         lang("want", false), | ||||
|         lang("assigned to", false), | ||||
|         lang("description", false), | ||||
|         lang("notes", false), | ||||
|         lang("comments", false) | ||||
|     ]; | ||||
|     $out = [$header]; | ||||
|     for ($i = 0; $i < count($items); $i++) { | ||||
|         $user = ""; | ||||
|         if (!is_null($items[$i]["userid"])) { | ||||
|             require_once __DIR__ . "/userinfo.php"; | ||||
|             $u = getUserByID($items[$i]["userid"]); | ||||
|             $user = $u['name'] . " (" . $u['username'] . ')'; | ||||
|         } | ||||
|         $out[] = [ | ||||
|             $items[$i]["itemid"], | ||||
|             $items[$i]["name"], | ||||
|             $items[$i]["catname"], | ||||
|             $items[$i]["locname"], | ||||
|             $items[$i]["code1"], | ||||
|             $items[$i]["code2"], | ||||
|             $items[$i]["qty"], | ||||
|             $items[$i]["want"], | ||||
|             $user, | ||||
|             $items[$i]["text1"], | ||||
|             $items[$i]["text2"], | ||||
|             $items[$i]["text3"] | ||||
|         ]; | ||||
|     } | ||||
|     return $out; | ||||
| } | ||||
| 
 | ||||
| function getCategoryReport() { | ||||
|     global $database; | ||||
|     $cats = $database->select('categories', [ | ||||
|         'catid', | ||||
|         'catname' | ||||
|     ]); | ||||
|     $header = [lang("id", false), lang("category", false), lang("item count", false)]; | ||||
|     $out = [$header]; | ||||
|     for ($i = 0; $i < count($cats); $i++) { | ||||
|         $itemcount = $database->count('items', ['catid' => $cats[$i]['catid']]); | ||||
|         $out[] = [ | ||||
|             $cats[$i]["catid"], | ||||
|             $cats[$i]["catname"], | ||||
|             $itemcount . "" | ||||
|         ]; | ||||
|     } | ||||
|     return $out; | ||||
| } | ||||
| 
 | ||||
| function getLocationReport() { | ||||
|     global $database; | ||||
|     $locs = $database->select('locations', [ | ||||
|         'locid', | ||||
|         'locname', | ||||
|         'loccode' | ||||
|     ]); | ||||
|     $header = [lang("id", false), lang("location", false), lang("code", false), lang("item count", false)]; | ||||
|     $out = [$header]; | ||||
|     for ($i = 0; $i < count($locs); $i++) { | ||||
|         $itemcount = $database->count('items', ['locid' => $locs[$i]['locid']]); | ||||
|         $out[] = [ | ||||
|             $locs[$i]["locid"], | ||||
|             $locs[$i]["locname"], | ||||
|             $locs[$i]["loccode"], | ||||
|             $itemcount . "" | ||||
|         ]; | ||||
|     } | ||||
|     return $out; | ||||
| } | ||||
| 
 | ||||
| function getReportData($type) { | ||||
|     switch ($type) { | ||||
|         case "item": | ||||
|             return getItemReport(); | ||||
|             break; | ||||
|         case "category": | ||||
|             return getCategoryReport(); | ||||
|             break; | ||||
|         case "location": | ||||
|             return getLocationReport(); | ||||
|             break; | ||||
|         case "itemstock": | ||||
|             return getItemReport(["AND" => ["qty[<]want", "want[>]" => 0]]); | ||||
|             break; | ||||
|         default: | ||||
|             return [["error"]]; | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| function dataToCSV($data, $name = "report") { | ||||
|     $csv = Writer::createFromString(''); | ||||
|     $csv->insertAll($data); | ||||
|     header('Content-type: text/csv'); | ||||
|     header('Content-Disposition: attachment; filename="' . $name . "_" . date("Y-m-d_Hi") . ".csv" . '"'); | ||||
|     echo $csv; | ||||
|     die(); | ||||
| } | ||||
| 
 | ||||
| function dataToODS($data, $name = "report") { | ||||
|     $ods = new ods(); | ||||
|     $styleColumn = new odsStyleTableColumn(); | ||||
|     $styleColumn->setUseOptimalColumnWidth(true); | ||||
|     $headerstyle = new odsStyleTableCell(); | ||||
|     $headerstyle->setFontWeight("bold"); | ||||
|     $table = new odsTable($name); | ||||
| 
 | ||||
|     for ($i = 0; $i < count($data[0]); $i++) { | ||||
|         $table->addTableColumn(new odsTableColumn($styleColumn)); | ||||
|     } | ||||
| 
 | ||||
|     $rowid = 0; | ||||
|     foreach ($data as $datarow) { | ||||
|         $row = new odsTableRow(); | ||||
|         foreach ($datarow as $cell) { | ||||
|             if ($rowid == 0) { | ||||
|                 $row->addCell(new odsTableCellString($cell, $headerstyle)); | ||||
|             } else { | ||||
|                 $row->addCell(new odsTableCellString($cell)); | ||||
|             } | ||||
|         } | ||||
|         $table->addRow($row); | ||||
|         $rowid++; | ||||
|     } | ||||
|     $ods->addTable($table); | ||||
|     $ods->downloadOdsFile($name . "_" . date("Y-m-d_Hi") . ".ods"); | ||||
| } | ||||
| 
 | ||||
| function dataToHTML($data, $name = "report") { | ||||
|     global $SECURE_NONCE; | ||||
|     // HTML exporter doesn't like null values
 | ||||
|     for ($i = 0; $i < count($data); $i++) { | ||||
|         for ($j = 0; $j < count($data[$i]); $j++) { | ||||
|             if (is_null($data[$i][$j])) { | ||||
|                 $data[$i][$j] = ''; | ||||
|             } | ||||
|         } | ||||
|     } | ||||
|     header('Content-type: text/html'); | ||||
|     $converter = new HTMLConverter(); | ||||
|     $out = "<!DOCTYPE html>\n" | ||||
|             . "<meta charset=\"utf-8\">\n" | ||||
|             . "<meta name=\"viewport\" content=\"width=device-width\">\n" | ||||
|             . "<title>" . $name . "_" . date("Y-m-d_Hi") . "</title>\n" | ||||
|             . <<<STYLE | ||||
| <style nonce="$SECURE_NONCE"> | ||||
|     .table-csv-data { | ||||
|         border-collapse: collapse; | ||||
|     } | ||||
|     .table-csv-data tr:first-child { | ||||
|         font-weight: bold; | ||||
|     } | ||||
|     .table-csv-data tr td { | ||||
|         border: 1px solid black; | ||||
|     } | ||||
| </style> | ||||
| STYLE | ||||
|             . $converter->convert($data); | ||||
|     echo $out; | ||||
| } | ||||
| 
 | ||||
| function generateReport($type, $format) { | ||||
|     $data = getReportData($type); | ||||
|     switch ($format) { | ||||
|         case "ods": | ||||
|             dataToODS($data, $type); | ||||
|             break; | ||||
|         case "html": | ||||
|             dataToHTML($data, $type); | ||||
|             break; | ||||
|         case "csv": | ||||
|         default: | ||||
|             echo dataToCSV($data, $type); | ||||
|             break; | ||||
|     } | ||||
| } | ||||
| @ -75,6 +75,14 @@ define("PAGES", [ | ||||
|             "static/js/editloc.js" | ||||
|         ], | ||||
|     ], | ||||
|     "export" => [ | ||||
|         "title" => "report export", | ||||
|         "navbar" => true, | ||||
|         "icon" => "download", | ||||
|         "scripts" => [ | ||||
|             "static/js/export.js" | ||||
|         ] | ||||
|     ], | ||||
|     "404" => [ | ||||
|         "title" => "404 error" | ||||
|     ] | ||||
|  | ||||
							
								
								
									
										40
									
								
								pages/export.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										40
									
								
								pages/export.php
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,40 @@ | ||||
| <?php | ||||
| 
 | ||||
| /* This Source Code Form is subject to the terms of the Mozilla Public | ||||
|  * License, v. 2.0. If a copy of the MPL was not distributed with this | ||||
|  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ | ||||
| 
 | ||||
| require_once __DIR__ . '/../required.php'; | ||||
| 
 | ||||
| redirectifnotloggedin(); | ||||
| ?>
 | ||||
| 
 | ||||
| <form action="lib/reports.php" method="GET" target="_BLANK"> | ||||
|     <div class="row"> | ||||
|         <div class="col-xs-12 col-sm-6"> | ||||
|             <label for="type"><?php lang("report type"); ?></label>
 | ||||
|             <select name="type" class="form-control" required> | ||||
|                 <option value="item"><?php lang("items") ?></option>
 | ||||
|                 <option value="category"><?php lang("categories") ?></option>
 | ||||
|                 <option value="location"><?php lang("locations") ?></option>
 | ||||
|                 <option value="itemstock"><?php lang("understocked items") ?></option>
 | ||||
|             </select> | ||||
|         </div> | ||||
|         <div class="col-xs-12 col-sm-6"> | ||||
|             <label for="type"><?php lang("format"); ?></label>
 | ||||
|             <select name="format" class="form-control" required> | ||||
|                 <option value="csv"><?php lang("csv file") ?></option>
 | ||||
|                 <option value="ods"><?php lang("ods file") ?></option>
 | ||||
|                 <option value="html"><?php lang("html file") ?></option>
 | ||||
|             </select> | ||||
|         </div> | ||||
|     </div> | ||||
|     <br /> | ||||
|     <?php | ||||
|     $code = uniqid(rand(10000000,99999999), true); | ||||
|     $database->insert('report_access_codes', ['code' => $code, 'expires' => date("Y-m-d H:i:s", strtotime("+5 minutes"))]); | ||||
|     ?>
 | ||||
|     <input type="hidden" name="code" value="<?php echo $code; ?>" /> | ||||
|      | ||||
|     <button type="submit" class="btn btn-success" id="genrptbtn"><i class="fa fa-download"></i> <?php lang("generate report"); ?></button>
 | ||||
| </form> | ||||
							
								
								
									
										9
									
								
								static/js/export.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										9
									
								
								static/js/export.js
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,9 @@ | ||||
| /* This Source Code Form is subject to the terms of the Mozilla Public | ||||
|  * License, v. 2.0. If a copy of the MPL was not distributed with this | ||||
|  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 | ||||
| 
 | ||||
| $("#genrptbtn").click(function () { | ||||
|     setTimeout(function () { | ||||
|         window.location.reload(); | ||||
|     }, 1000) | ||||
| }); | ||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user