src/Controller/PlanControoler.php line 43

Open in your IDE?
  1. <?php
  2. /**
  3.  * 生産計画管理用コントローラー
  4.  * 
  5.  */
  6. namespace App\Controller;
  7. use Symfony\Component\Routing\Annotation\Route;
  8. use Symfony\Component\HttpFoundation\Response;
  9. use Symfony\Component\HttpFoundation\Request;
  10. use Symfony\Component\HttpFoundation\JsonResponse;
  11. use App\Controller\BaseController;
  12. use App\Service\KintoneService;
  13. use App\Service\CommonService;
  14. use DateTime;
  15. class PlanControoler extends BaseController
  16. {
  17.     protected $kintoneService;
  18.     protected $commonService;
  19.     /** @var Psr\Log\LoggerInterface logger */
  20.     protected $logger;
  21.     public function __construct(
  22.         KintoneService $kintoneService,
  23.         CommonService $commonService,
  24.         \Psr\Log\LoggerInterface $logger
  25.     )
  26.     {
  27.         parent::__construct();
  28.         $this->kintoneService $kintoneService;
  29.         $this->commonService $commonService;
  30.         $this->logger $logger;
  31.     }
  32.     /**
  33.      * @param Request $request
  34.      * 
  35.      * @Route("/plan", name="plan")
  36.      */    
  37.     public function index(Request $request): Response
  38.     {
  39.         return $this->getPlanData($request"html");
  40.     }
  41.     /**
  42.      * @param Request $request
  43.      * @param string $response_type (html/json)
  44.      */    
  45.     private function getPlanData($request$response_type) {
  46.         $data["date"] = $request->get('search_date'date("Y-m-d"));
  47.         $data["machine"] = $request->get('search_machine'"1号機");
  48.         $search["machine"] = $data["machine"];
  49.         $increment_qty = [];    // 仕掛りで作る予定の数
  50.         $decrement_qty = [];    // 受注して在庫から減る予定の数
  51.         $arrangement_item = []; //手配商品
  52.         $this->getRemainingData($increment_qty$arrangement_item$data);
  53.         $data["arrangement"] = $arrangement_item;
  54.         $start $data["date"];
  55.         $end date("Y-m-d"strtotime($start '+11 day'));
  56.         //指定した出荷予定日以降+5日の受注データ取得
  57.         $result $this->kintoneService->requestGets('order'sprintf('出荷予定日_0 >= "%s" and 出荷予定日_0 < "%s" limit 500'$data["date"], $end));
  58.         $records $result["records"];
  59.         // 出荷する商品数をセット
  60.         foreach($records as $record) {
  61.             $sub_table $record["受注商品テーブル"]["value"];
  62.             $delivery_date $record["出荷予定日_0"]["value"];
  63.             //分類で生産管理の判別をする
  64.             //項目 "通常の受注", "①外部倉庫・無償サンプル発送", "②仕入れ販売・外部倉庫出庫", "③当社へ引き取り", "④発送のみ", "⑤無償サンプル引き取り"
  65.             $bunrui $record['分類']["value"];
  66.             $target_bunrui = ['通常の受注''①外部倉庫・無償サンプル発送''③当社へ引き取り''⑤無償サンプル引き取り'];
  67.             if(in_array($bunrui$target_bunrui)) {
  68.                 foreach($sub_table as $row){
  69.                     $item $row["value"];
  70.                     $item_code $item["商品コード"]["value"];
  71.     
  72.                     $qty $item["箱数"]["value"] ? $item["箱数"]["value"] : 0;
  73.                     if(isset($decrement_qty[$item_code])) $decrement_qty[$item_code]+= $qty;
  74.                     else                                  $decrement_qty[$item_code] = $qty;
  75.                 }
  76.             }
  77.         }
  78.         //在庫マスタからデータ取得
  79.         $offset 0;
  80.         $limit 100;
  81.         $data["item"] = [];
  82.         $data["unarrangement"] = [];
  83.         while(1) {
  84.             $query sprintf(' 手作業 not in ("レ")  order by レコード番号 limit %d offset %d'$limit$offset);
  85.             $result $this->kintoneService->requestGets('stock'$query);
  86.             foreach($result["records"] as $item) {
  87.                 $line $item["製造号機"]["value"];
  88.                 $film $item["フィルムの種類"]["value"];
  89.                 $film_addr $item["フイルム住所・棚番"]["value"];
  90.                 $item_name $item["商品名"]["value"];
  91.                 $item_code $item["商品コード"]["value"];
  92.                 $stock_limit $item["最低在庫数"]["value"];
  93.                 $stock $item["在庫数"]["value"];
  94.                 //商品マスタ
  95.                 $data["item"][$item_code] = [
  96.                     "code" => $item_code,
  97.                     "name" => $item_name,
  98.                     "film" => $film,
  99.                     "film_addr" => $film_addr,
  100.                     "line" => $line,
  101.                     "limit" => $stock_limit,
  102.                     "stock" => $stock
  103.                 ];
  104.                 //生産可能リストを作成
  105.                 //$qty = is_numeric($stock) ? $stock : 0;
  106.                 $qty $stock;
  107.                 // +5日分の受注数を減算する
  108.                 if( isset($decrement_qty[$item_code]) && is_numeric($decrement_qty[$item_code]) ) $qty-= $decrement_qty[$item_code];
  109.                 // 仕掛りで作られるであろう数を加算する 仕掛り分は減らさない
  110.                 if( isset($increment_qty[$item_code]) && is_numeric($increment_qty[$item_code])  ) $qty+= $increment_qty[$item_code];
  111.                 // 「仕掛りがある」もしくは「在庫数が目安より少なくなった」場合は 生産可能リストとして配列に持たす
  112.                 if($stock_limit $qty || isset($increment_qty[$item_code]) ){
  113.                     //未手配の商品を製造機毎に配列で持たす
  114.                     foreach($line as $tmp_line){
  115.                        if(!is_numeric($qty) || !is_numeric($stock_limit)) {
  116.                           echo sprintf("商品コード:[%s] 在庫もしくは最低在庫数が数値ではありません。<br>kintone在庫アプリを確認してください。<br>※kintoneの修正後、反映に時間がかかる場合があります。"$item_code);
  117.                           exit;
  118.                        }else{
  119.                             $data["unarrangement"][$tmp_line][$item_code] = [
  120.                                 "num" => $stock_limit $qty $stock_limit $qty 0,
  121.                             ];
  122.                        }
  123.                     }
  124.                 }
  125.             }
  126.             $offset += $limit;
  127.             if($result["totalCount"] < $offset) {
  128.                 break;
  129.             }
  130.             if($offset >= 10000 ) {
  131.                 echo '無限ループの可能性があります';
  132.                 break;
  133.             }
  134.         }
  135.         if($response_type == "html") {
  136.             return $this->render('plan.html.twig', [
  137.                 "data" => $data,
  138.                 "json_items" => json_encode($data["item"]),
  139.                 "json_unarrangement" => json_encode($data["unarrangement"]),
  140.                 "json_arrangement" => json_encode($data["arrangement"]),
  141.                 'machine_list' => $this->getOriginalConfig("param""machines"),
  142.                 "search" => $search,
  143.             ]);
  144.         }else{
  145.             $params = [
  146.                 "json_items" => $data["item"],
  147.                 "json_unarrangement" => $data["unarrangement"],
  148.                 "json_arrangement" => $data["arrangement"],
  149.             ];
  150.             return new JsonResponse($params);
  151.         }
  152.     }
  153.     /**
  154.      * データの追加・修正
  155.      * @Route("/plan/set_plan", name="set_plan")
  156.      */
  157.     public function setPlan(Request $request){
  158.         $search_date $request->get('search_date');
  159.         $line $request->get('line');
  160.         $set_item $request->get('set_item');
  161.         $mode $request->get('mode');
  162.         if($mode == "regist"$disp_mode "追加";
  163.         elseif($mode == "edit"$disp_mode "修正";
  164.         elseif($mode == "sort"$disp_mode "並び替え";
  165.         $this->logger->log("debug"sprintf("update Plan date:%s line:%s items:%s:"$search_date$linejson_encode($set_item) ));
  166.         //現状を取得
  167.         $query sprintf('手配日 = "%s" and 製造号機 in ("%s")'$search_date$line);
  168.         $result $this->kintoneService->requestGets('production_management'$query);
  169.         $no $this->commonService->convertNo($set_item["no"]);
  170.         $update_date $this->commonService->getDateTimeUTC();
  171.         $tmp = [
  172.             "No" => $no,
  173.             "急ぎ" => $set_item["quickly"] == "1" ? ["急ぎ"] : [],
  174.             "ケース" => $set_item["num"],
  175.             "商品コード" => $set_item["item_code"],
  176.             "key" => $set_item["key"],
  177.             "最終更新日時" => $update_date
  178.         ];
  179.         $fh fopen(__DIR__ "/log.txt""w");
  180.         fputs($fhprint_r($tmptrue));
  181.         fclose($fh);
  182.         $new_items = [];
  183.         if(!empty($result['records'])) {
  184.             $records $result['records'];
  185.             foreach($records as $record){
  186.                 $kintone_id $record['$id']['value'];
  187.                 $table $record['手配状況']['value'];
  188.                 $exist_flg false;
  189.                 foreach($table as $item) {
  190.                     if( $item['value']['key']['value'] == $set_item["key"] ) {
  191.                         $exist_flg true;
  192.                         $complete_num $item['value']['完了数']['value'];
  193.                         if($tmp["ケース"] <= $complete_num) {
  194.                             $tmp["完了"] = ["完了"];
  195.                         }else{
  196.                             $tmp["完了"] = [];
  197.                         }
  198.                         $new_items[] = [ "id" => $item["id"], "value" => $this->kintoneService->setAttribute($tmp) ];
  199.                     }else{
  200.                         $new_items[] = [ "id" => $item["id"] ];
  201.                     }
  202.                 }
  203.                 if(!$exist_flg) {
  204.                     $new_items[] = [ "value" => $this->kintoneService->setAttribute($tmp) ];
  205.                 }
  206.                 $log $this->create_log($record['更新履歴']['value'], $disp_mode$update_date);
  207.                 $management["手配状況"] = $new_items;
  208.                 $management["更新履歴"] = $log;
  209.                 $management["全て完了"] = [];
  210.                 $management_data $this->kintoneService->setAttribute($management);
  211.                 $this->kintoneService->requestPut("production_management"$kintone_id$management_data);
  212.             }
  213.         }else{
  214.             $log $this->create_log([], $disp_mode$update_date);
  215.             $new_items[] = [ "value" => $this->kintoneService->setAttribute($tmp) ];
  216.             $management["製造号機"] = $line;
  217.             $management["手配日"] = $search_date;
  218.             $management["手配状況"] = $new_items;
  219.             $management["更新履歴"] = $log;
  220.             $management["手配状況"] = $new_items;
  221.             $management["全て完了"] = [];
  222.             $management_data $this->kintoneService->setAttribute($management);
  223.             $this->kintoneService->requestPost("production_management"$management_data);
  224.         }
  225.         //return $this->getPlanData($request, "json");
  226.         return new JsonResponse(["result" => true]);
  227.     }
  228.     /**
  229.      * データの取り消し
  230.      * @Route("/plan/del_plan", name="del_plan")
  231.      */
  232.     public function delPplan(Request $request){
  233.         $search_date $request->get('search_date');
  234.         $line $request->get('line');
  235.         $key $request->get('key');
  236.         /*
  237.         テストデータ
  238.         $search_date = "2024-10-16";
  239.         $line = "4号機";
  240.         $key = "1929e7de919d9";
  241.         */
  242.         $this->logger->log("debug"sprintf("delete Plan date:%s line:%s key:%s:"$search_date$line$key));
  243.         //現状を取得
  244.         $query sprintf('手配日 = "%s" and 製造号機 in ("%s")'$search_date$line);
  245.         $result $this->kintoneService->requestGets('production_management'$query);
  246.         $update_date $this->commonService->getDateTimeUTC();
  247.         foreach($result['records'] as $record) {
  248.             $kintone_id $record['$id']['value'];
  249.             $table $record['手配状況']['value'];
  250.             $new_items = [];
  251.             $all_complete true;
  252.             foreach($table as $item) {
  253.                 if( $item['value']['key']['value'] != $key) {
  254.                     $new_items[] = ["id" => $item["id"]];
  255.                     if(!in_array("完了"$item["value"]["完了"]["value"])) {
  256.                         $all_complete false;
  257.                     }
  258.                 }else{
  259.                     $tmp = [];
  260.                     $tmp["完了"] = $item["value"]["完了"]["value"];
  261.                     $tmp["完了"][] = "取消し";
  262.                     $tmp["最終更新日"] = $update_date;
  263.                     $new_items[] = [ "id" => $item["id"], "value" => $this->kintoneService->setAttribute($tmp) ];
  264.                 }
  265.             }
  266.             $management["手配状況"] = $new_items;
  267.             $management["更新履歴"] = $this->create_log($record['更新履歴']['value'], '取消し'$update_date);
  268.             if($all_complete) {
  269.                 $management["全て完了"] = ["完了"];
  270.             }
  271.             
  272.             $management_data $this->kintoneService->setAttribute($management);
  273.         }
  274.         $result $this->kintoneService->requestPut("production_management"$kintone_id$management_data);
  275.     }
  276.     /**
  277.      * データの並び替え
  278.      * @Route("/plan/sort_plan", name="sort_plan")
  279.      */
  280.     public function sortPlan(Request $request){
  281.         $search_date $request->get('search_date');
  282.         $line $request->get('line');
  283.         $items $request->get('items');
  284.         //現状を取得
  285.         $query sprintf('手配日 = "%s" and 製造号機 in ("%s")'$search_date$line);
  286.         $result $this->kintoneService->requestGets('production_management'$query);
  287.         $update_date $this->commonService->getDateTimeUTC();
  288.         foreach($result['records'] as $record) {
  289.             $kintone_id $record['$id']['value'];
  290.             $table $record['手配状況']['value'];
  291.             $new_items = [];
  292.             foreach($items as $item){
  293.                 foreach($table as $row) {
  294.                     if($row["value"]["key"]["value"] == $item["key"]) {
  295.                         $row["value"]["最終更新日"]["value"] = $update_date;
  296.                         $new_items[] = $row;
  297.                         break;
  298.                     }
  299.                 }
  300.             }
  301.             $management["手配状況"] = $new_items;
  302.             $management["更新履歴"] = $this->create_log($record['更新履歴']['value'], '並び替え'$update_date);
  303.             $management_data $this->kintoneService->setAttribute($management);
  304.             $result $this->kintoneService->requestPut("production_management"$kintone_id$management_data);
  305.         }
  306.     }
  307.     /**
  308.      * 生産計画
  309.      * @Route("/manufacturing", name="manufacturing")
  310.      */
  311.     public function manufacturing(Request $request){
  312.         $today $request->get('today'date('Y-m-d'));
  313.         $line $request->get('line');
  314.         //$query = sprintf('手配日 = "%s" and 製造号機 in ("%s")', $today, $line);
  315.         $query sprintf('製造号機 in ("%s") and (手配日 = "%s" or (手配日 < "%s" and 全て完了 not in ("完了"))) order by 手配日 asc'$line$today$today);
  316.         $result $this->kintoneService->requestGets('production_management'$query);
  317.         $item_codes = [];
  318.         foreach($result['records'] as $record) {
  319.             $table $record['手配状況']['value'];
  320.             $arrangement_date $record['手配日']['value'];
  321.             foreach($table as $row) {
  322.                 if(count($row["value"]["完了"]["value"])) continue;
  323.                 if(empty($row["value"]["商品コード"]["value"])) continue;
  324.                 $item_code $row["value"]["商品コード"]["value"];
  325.                 if(!isset($item_codes[$arrangement_date])) $item_codes[$arrangement_date] = [];
  326.                 $item_codes[$arrangement_date][] = $item_code;
  327.                 $qty = (int)$row["value"]["ケース"]["value"] - (int)$row["value"]["完了数"]["value"];
  328.                 if(!isset($order_qty[$arrangement_date])) $order_qty[$arrangement_date] = [];
  329.                 /*
  330.                 if(isset($order_qty[$arrangement_date][$item_code])) {
  331.                     $order_qty[$arrangement_date][$item_code]+= $qty;
  332.                     $order_no[$arrangement_date][$item_code][] = $this->commonService->convertDispNo($row["value"]["No"]["value"], $row["value"]["完了No"]["value"]);
  333.                 }else{
  334.                     $order_qty[$arrangement_date][$item_code] = $qty;
  335.                     $order_no[$arrangement_date][$item_code][] = $this->commonService->convertDispNo($row["value"]["No"]["value"], $row["value"]["完了No"]["value"]);
  336.                 }
  337.                 */
  338.                 $order[$arrangement_date][] = [
  339.                     "item_code" => $item_code,
  340.                     "no" => $this->commonService->convertDispNo($row["value"]["No"]["value"], $row["value"]["完了No"]["value"]),
  341.                     "qty" => $qty
  342.                 ];
  343.             }
  344.         }
  345.         $data["item"] = [];
  346.         //在庫マスタからデータ取得
  347.         foreach($item_codes as $date_val => $date_list) {
  348.             $query sprintf('商品コード in (%s) order by レコード番号''"' join('","'$date_list) . '"');
  349.             $result $this->kintoneService->requestGets('stock'$query);
  350.             foreach($result["records"] as $record) {
  351.                 $film $record["フィルムの種類"]["value"];
  352.                 $film_addr $record["フイルム住所・棚番"]["value"];
  353.                 $item_name $record["商品名"]["value"];
  354.                 $item_code $record["商品コード"]["value"];
  355.     
  356.                 $item[$item_code] = [
  357.                     "name" => $item_name,
  358.                     "film" => $film,
  359.                     "film_addr" => $film_addr,
  360.                 ];
  361.             }
  362.         }
  363.         //リストを作成
  364.         /*
  365.         foreach($item_codes as $date_val => $date_list) {
  366.             foreach($date_list as $item_code) {
  367.                 $diff = $order_qty[$date_val][$item_code];
  368.                 $no = $order_no[$date_val][$item_code];
  369.                 $data["item"][$date_val][] = [
  370.                     "code" => $item_code,
  371.                     "name" => $item[$item_code]["name"],
  372.                     "no" => $no,
  373.                     "film" => $item[$item_code]["film"],
  374.                     "film_addr" => $item[$item_code]["film_addr"],
  375.                     "diff" => $diff,
  376.                 ];
  377.             }
  378.         }
  379.         */
  380.         foreach($order as $date_val => $order_val){
  381.             foreach($order_val as $val){
  382.                 $item_code $val["item_code"];
  383.                 $data["item"][$date_val][] = [
  384.                     "code" => $item_code,
  385.                     "name" => $item[$item_code]["name"],
  386.                     "no" => $val["no"],
  387.                     "film" => $item[$item_code]["film"],
  388.                     "film_addr" => $item[$item_code]["film_addr"],
  389.                     "diff" => $val["qty"],
  390.                 ];
  391.             }
  392.         }
  393.         $data["line"] = $line;
  394.         return $this->render('manufacturing.html.twig', [
  395.             "today" => $today,
  396.             "data" => $data,
  397.         ]);
  398.     }
  399.     /**
  400.      * 更新履歴用のデータ作成
  401.      *
  402.      * @param [type] $logs
  403.      * @param [type] $mode
  404.      * @return void
  405.      */
  406.     private function create_log($logs$mode$update_date){
  407.         $new_log = [];
  408.         foreach($logs as $item){
  409.             $new_log[] = ["id" => $item["id"]];
  410.         }
  411.         $new_log[] = [ "value" =>  $this->kintoneService->setAttribute([
  412.             "ページ" => "生産計画管理",
  413.             "処理内容" => $mode,
  414.             "処理日時" => $update_date,
  415.         ])];
  416.         return $new_log;
  417.     }
  418.     /**
  419.      * 仕掛りのデータ取得
  420.      * @param array $item_codes
  421.      * 
  422.      * @return array
  423.      */
  424.     private function getRemainingData(&$add_qty, &$arrangement_item$data){
  425.         //完了していない手配済みリストを取得
  426.         $query sprintf('手配日 = "%s" or (手配日 < "%s" and 完了 not in ("完了","取消し")) order by 手配日 asc'$data["date"], $data["date"]);
  427.         $result $this->kintoneService->requestGets('production_management'$query);
  428.         $records $result["records"];
  429.         foreach($records as $record){
  430.             $line $record["製造号機"]["value"];
  431.             $arrangement_list $record["手配状況"]["value"];
  432.             $complete $record["全て完了"]["value"];
  433.             $arrangement_date $record["手配日"]["value"];
  434.             foreach($arrangement_list as $tmp_item) {
  435.                 $item $tmp_item["value"];
  436.                 $item_code $item["商品コード"]["value"];
  437.                 if(empty($item_code)) continue;
  438.                 if(in_array("取消し"$item["完了"]["value"])) continue;
  439.                 $num = (int)$item["ケース"]["value"];
  440.                 if(!in_array("完了"$item["完了"]["value"])) {
  441.                     // 設定したNoと完了したNoの差分を出す
  442.                     $no $this->commonService->convertDispNo($item["No"]["value"], $item["完了No"]["value"]);
  443.                     $default_no $this->commonService->convertDispNo($item["No"]["value"], ""); //とりあえず設定した内容を表示
  444.                     $complete_num = (int)$item["完了数"]["value"];
  445.                     $key $item["key"]["value"];
  446.                     $quickly = !empty($item["急ぎ"]["value"]) ? true false;
  447.                     $diff $num $complete_num;
  448.                     if(empty($complete) && $item_code) {
  449.                         $arrangement_item[$line][$arrangement_date][] = [
  450.                             "item_code" => $item_code,
  451.                             "num" => $num,
  452.                             "no" => $no,
  453.                             "default_no" => $default_no,
  454.                             "complete_num" => $complete_num,
  455.                             "diff" => $diff,
  456.                             "key" => $key,
  457.                             "quickly" => $quickly,
  458.                         ];
  459.                     }
  460.                     // 仕掛りの残り生産数を計算する
  461.                     if(isset($total_arrangement[$item_code])) {
  462.                         $add_qty[$item_code]+= $diff;
  463.                     }else{
  464.                         $add_qty[$item_code] = $diff;
  465.                     }
  466.                 }
  467.             }
  468.         }
  469.     }
  470. }