<?php
/**
* 生産実績管理用コントローラー
*
*/
namespace App\Controller;
use Symfony\Component\Routing\Annotation\Route;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\JsonResponse;
use App\Controller\BaseController;
use App\Service\KintoneService;
use App\Service\CommonService;
use Symfony\Component\Filesystem\Filesystem;
class StockControoler extends BaseController
{
protected $kintoneService;
protected $commonService;
protected $logger;
public function __construct(
KintoneService $kintoneService,
CommonService $commonService,
\Psr\Log\LoggerInterface $logger
)
{
parent::__construct();
$this->kintoneService = $kintoneService;
$this->commonService = $commonService;
$this->logger = $logger;
}
/**
* @Route("/stock", name="stock")
*/
public function index(Request $request): Response
{
//検査者のリストを取得
$query = "order by 表示順 asc";
$result = $this->kintoneService->requestGets('staff', $query);
$records = $result["records"];
$staff = [];
foreach($records as $record) $staff[] = $record["検査者"]["value"];
//指定日の生産管理データ取得
$today = $request->get('today', date("Y-m-d"));
//$query = sprintf('手配日 = "%s"', $today);
$query = sprintf('手配日 = "%s" or (手配日 < "%s" and 全て完了 not in ("完了")) order by 製造号機 asc, 手配日 asc', $today, $today);
$result = $this->kintoneService->requestGets('production_management', $query);
$records = $result["records"];
$item_codes = [];
$arrangement_item = [];
foreach($records as $record){
$line = $record["製造号機"]["value"];
$arrangement_list = $record["手配状況"]["value"];
$all_complete = $record["全て完了"]["value"];
$arrangement_date = $record["手配日"]["value"];
foreach($arrangement_list as $tmp_item) {
$id = $tmp_item["id"];
$item = $tmp_item["value"];
$item_code = $item["商品コード"]["value"];
if(empty($item_code)) continue;
$no = $this->commonService->convertDispNo($item["No"]["value"], $item["完了No"]["value"]);
$num = (int)$item["ケース"]["value"];
$complete_num = (int)$item["完了数"]["value"];
$key = $item["key"]["value"];
$complete = $item["完了"]["value"];
$quickly = !empty($item["急ぎ"]["value"]) ? true : false;
if(empty($complete)) {
$arrangement_item[$line][$arrangement_date][] = [
"id" => $id,
"item_code" => $item_code,
"num" => $num,
"no" => $no,
"complete_num" => $complete_num,
"diff" => $num - $complete_num,
"key" => $key,
"quickly" => $quickly,
];
}
if(!in_array($item_code, $item_codes)) $item_codes[] = $item_code;
}
}
$data["arrangement"] = $arrangement_item;
$query = sprintf('商品コード in (%s) order by レコード番号', '"' . join('","', $item_codes) . '"');
$result = $this->kintoneService->requestGets('stock', $query);
$data["item"] = [];
foreach($result["records"] as $item) {
$item_name = $item["商品名"]["value"];
$item_code = $item["商品コード"]["value"];
//商品マスタ
$data["item"][$item_code] = [
"code" => $item_code,
"name" => $item_name,
];
}
$search["machine"] = $request->get('search_machine');
return $this->render('stock.html.twig', [
"today" => $today,
"json_items" => json_encode($data["item"]),
"json_arrangement" => json_encode($data["arrangement"]),
"json_memo" => json_encode($this->getMemo(true)),
"json_log" => json_encode($this->getStockLog()),
"staff" => $staff,
'machine_list' => $this->getOriginalConfig("param", "machines"),
"search" => $search,
]);
}
/**
* @Route("/set_stock", name="set_stock")
*/
public function setStock(Request $request)
{
$search_date = $request->get('search_date');
$line = $request->get('line');
$key = $request->get('key');
$qty = $request->get('qty');
$no = $request->get('no');
$staff = $request->get('staff');
$add_complete_no = $this->commonService->convertNo($no);
$this->logger->log("debug", sprintf("set stock date:%s line:%s key:%s qty:%s", $search_date, $line, $key, $qty ));
//現状を取得
$query = sprintf('手配日 = "%s" and 製造号機 in ("%s")', $search_date, $line);
$result = $this->kintoneService->requestGets('production_management', $query);
$stock_code = "";
$add_qty = $qty;
foreach($result["records"] as $record){
$kintone_id = $record['$id']['value'];
$arrangement_list = $record["手配状況"]["value"];
$all_complete = true;
foreach($arrangement_list as $tmp_item) {
$item = $tmp_item["value"];
$id = $tmp_item["id"];
if(empty($item["商品コード"]["value"])) continue;
$stock_code = $item["商品コード"]["value"];
if($key == $item["key"]["value"]) {
$num = (int)$item["ケース"]["value"];
$complete_num = (int)$item["完了数"]["value"] + $qty;
if($num <= $complete_num) $item_complete = ["完了"];
else {
$item_complete = [];
$all_complete = false;
}
//既存の状態 + 追加分
$complete_no = $item["完了No"]["value"] ? $item["完了No"]["value"] . "," . $add_complete_no : $add_complete_no;
$tmp = [
"完了数" => $complete_num,
"完了No" => $complete_no,
"完了" => $item_complete
];
$new_items[] = [ "id" => $id, "value" => $this->kintoneService->setAttribute($tmp) ];
//ログを残す
$log_params = [
"item_code" => $item["商品コード"]["value"],
"item_name" => $item["商品名"]["value"],
"qty" => $qty,
"no" => $no,
"staff" => $staff,
"num" => $num,
"complete_num" => $complete_num,
"complete" => join(",", $item_complete)
];
$this->setStockLog($line, $log_params);
$update_stock_code = $item["商品コード"]["value"];
}else{
if(empty($item["完了"]["value"])) $all_complete = false;
$new_items[] = [ "id" => $id ];
}
}
}
if(!empty($new_items)) {
$management["手配状況"] = $new_items;
if($all_complete) {
$management["全て完了"] = ["完了"];
}
$management_data = $this->kintoneService->setAttribute($management);
$result = $this->kintoneService->requestPut("production_management", $kintone_id, $management_data);
}
//在庫のセット
if($update_stock_code){
$query = sprintf('商品コード = "%s" order by レコード番号', $update_stock_code);
$result = $this->kintoneService->requestGets('stock', $query);
foreach($result['records'] as $record) {
$kintone_id = $record['$id']['value'];
$stock_data['在庫数']['value'] = $record['在庫数']['value'] + $add_qty;
//$this->logger->log("debug", sprintf("record_id:%s: new stock_count: %d", $kintone_id, $stock_data['在庫数'] ));
$result = $this->kintoneService->requestPut("stock", $kintone_id, $stock_data);
}
}
return new JsonResponse(["log" => $this->getStockLog()]);
}
/**
* @Route("/stock/setMemo", name="stock_set_memo")
*/
public function seMemo(Request $request){
$line_id = $request->get('line_id');
$memo = $request->get('memo');
$this->logger->info('POSTデータ', ["line_id" => $line_id, "memo" => $memo]);
$path = $this->getStockMemoFileName($line_id);
$fh = fopen($path, "w");
fputs($fh, $memo);
fclose($fh);
return new JsonResponse($this->getMemo());
}
/**
* 保存されている製造号機ごとのメモを取得 function
*
* @param string $line_id
* @return array
*/
private function getMemo($escape_flg = false){
foreach($this->getOriginalConfig("param", "machines") as $key => $value) {
$path = $this->getStockMemoFileName($key);
$memo[$key] = is_file($path) ? file_get_contents($path) : "";
if($escape_flg) {
$memo[$key] = preg_replace("/\n/","\\n", $memo[$key]);
}
}
return $memo;
}
/**
* 製造号機ごとのメモファイルを取得
*
* @param [type] $machine_id
* @return string
*/
private function getStockMemoFileName($machine_id){
$path = __DIR__ . "/../../data/stock/{$machine_id}.tsv";
return $path;
}
/**
* 製造号機の値からIDを取得
*
* @param [type] $line
* @return void
*/
private function getMachineId($line){
foreach($this->getOriginalConfig("param", "machines") as $key => $value) {
if($line == $value) return $key;
}
}
/**
* 製造号機ごとにログを残す
*
* @param [type] $line
* @param [type] $params
*/
private function setStockLog($line, $log_params) {
$machine_id = $this->getMachineId($line);
$path = $this->getStockLogFileName( $machine_id );
$lock_handler = $this->lfFileLock($path);
$lines = date("Y-m-d H:i:s") . "\t" . serialize($log_params) . "\n";
$data = is_file($path) ? file($path) : [];
//とりあえず100行分残す
for($i=0; $i<count($data); $i++) {
$row = trim($data[$i]);
if(empty($row)) continue;
$lines.= $row . "\n";
if($i == 100) break;
}
$fh = fopen($path, "w");
fputs($fh, $lines);
fclose($fh);
if(!$lock_handler) {
$this->logger->debug('ロックエラー', ["file" => $path, "param" => $log_params]);
}else{
fclose($lock_handler);
}
}
/**
* 製造号機ごとのログファイルを取得
*
* @param [type] $machine_id
* @param [type] $date
* @return string
*/
private function getStockLogFileName($machine_id, $date = null) {
if(is_null($date)) $date = date("Y-m");
$path = __DIR__ . "/../../data/stock/{$machine_id}_log.tsv";
return $path;
}
/**
* 製造号機ごとの操作ログを取得
*
* @param [type] $date
* @return array
*/
private function getStockLog($date = null) {
$logs = [];
foreach($this->getOriginalConfig("param", "machines") as $key => $value) {
$path = $this->getStockLogFileName($key);
$rows = is_file($path) ? file($path) : [];
$logs[$key] = [];
foreach($rows as $row){
$row = trim($row);
if(empty($row)) continue;
$log_data = preg_split("/\t/", $row);
$logs[$key][] = [
"datetime" => $log_data[0],
"log" => !empty($log_data[1]) ? unserialize($log_data[1]) : null,
];
}
}
return $logs;
}
}