見出し画像

webix画面からQRラベル印刷機能の実装

前回、備品管理用機能を実装した事例を紹介しましたが、その機能で、保管場所一覧にチェックボックスを追加して、複数の保管場所情報を選択して、QRコードラベルを印刷機能を紹介します。印刷したQRコードラベルは、それぞれの保管場所に貼ります。備品のQRコードと保管場所のQRコードを使用して、備品の保管先をQRコード操作で対応づける機能が最終目標です。
今回は、保管先のQRコードラベル印刷を紹介します。今後、備品についても保管先と同じように機能を実装(一覧、新規登録、編集、削除、EXCELインポート、QRコード印刷など)すればQRコードをスマホで操作し、備品管理ができるようになります。
前回から修正した機能は、以下のとおりです。

webix01/view/LC0010/LC0010_locations_lists.php          一覧にチェックボックスと印刷ボタン実装(変更)
webix01/rest_api/LC0010/LC0019_print_locationlabels.php QRコードラベル印刷指示用REST_API(追加)
webix01/config/app01.php                                各種環境定義用config(変更)

印刷機能(C#) tepra_print.exe    QRコードに名称を含めないフォーマットに変更
印刷フォーム bihin_12.tpe       項目情報の幅変更(全長を短くするため)

webixのチェックボックス機能を使い、一覧から複数行を選択できるようにしました。選択した状態でQR印刷をクリックすると、サーバ側(PHP)に印刷要求をだします。LC0019_print_locationlabels.phpで複数行の情報を受け取り、順番にQRラベル印刷指示をcurlコマンドを使って、TEPRA印刷機能(tepra_print.exe)が動作しているPCに依頼します。
tepra_print.exeでは、要求を受信すると、CSVファイルを作成してTEPRAプリンタに印刷指示を出します。
一覧画面では、チェックした行の情報を取り出し、連想配列に代入後に、JSON.stringifyで、文字列化してサーバに送信します。
サーバ側(PHP)では、json_decodeを使って、連想配列に戻し、1行づつ、印刷指示をcurlで依頼します。PHPが動作スルサーバ(Linux)からTEPRA印刷が動作するWindows10のPCへの依頼は、PC側のC#で簡易Webサーバを実装して要求を受信し、PHPからの印刷要求の情報をCSVにしてTEPRAプリンタに印刷指示を出します。
印刷が正常に終了すると、該当レコードのメモに、印刷済と追記してデータを更新します。
以下は、5件選択して印刷をした結果画面です。メモに印刷済と追記されます。

実際に印刷したラベルです。5枚印刷されました。

画面ソースの修正箇所だけ記載します。LC0010_locations_lists.php

//QRラベル印刷処理
function LC0010_print_QRlabel(print_lists){
    var formData = new FormData();
    var access_key = Get_AccessKey();
    formData.append("accesskey",access_key);
    formData.append("userid",  my_local_session.userid);
    formData.append("job_info","LC0010");
    formData.append("print_lists",JSON.stringify(print_lists));
    var xhr =webix.ajax().sync().post("<?php  echo SUB_FOLDER; ?>/rest_api/LC0010/LC0019_print_locationlabels.php",formData);
    var resp =  JSON.parse(xhr.responseText);
    if(resp.resp =="ok"){
        LC0010_select_locations_lists();
        webix.message({type:"success",text:"QRラベルを印刷しました。"});
        return;
    }
    else{
        webix.alert("QRラベルの印刷処理でエラーしました。 code="+resp.error_code);
        return;
    }
}




                { align:"top", body:{ view:"button",id:"LC0010_print_QRlabel_btn", name:"LC0010_print_QRlabel_btn", value: "QR印刷", align:"center", width: 110, css:"webix_danger", 
                    click:function(){
                        var print_lists = [];
                        var cnt = 0;
                        $$("LC0010_table").eachRow(function(row){ 
                            const record = $$("LC0010_table").getItem(row);
                            if(record.ch1 == 1){
                                cnt += 1;
                                print_lists.push(record);
                            }
                        });
                        if(cnt == 0){
                            webix.alert("QRラベル印刷<br>対象の行がありません。");
                            return;
                        }
                        else{
                            webix.confirm({
                                title:"確認",
                                ok:"はい", 
                                cancel:"いいえ",
                                text:cnt+"件、<br>QRラベルを印刷しますか?"
                            })
                            .then(function(result){
                                LC0010_print_QRlabel(print_lists);
                            })
                            .fail(function(){
                                webix.message({type:"debug",text:"印刷操作をキャンセルしました。"});
                            });
                        }
                    }
                }},







    var grid1 = {
        id: "LC0010_table",
        name: "LC0010_table",
        type:"clean",
        view:"datatable",
        width:800,
        resizeColumn:true,
        resizeRow: { headerOnly:true },             
        columns:[
            { id:"ch1", header:{ content:"masterCheckbox", contentId:"cm1"}, template:"{common.checkbox()}", width:40 },
            { id:"id",header:["id",{content:"textFilter"}],width:100,sort:"int", css:{"text-align":"right"}},
            { id:"code",header:["保管先コード",{content:"textFilter"}],width:100,sort:"int", css:{"text-align":"right"}},
            { id:"area",header:["場所",{content:"selectFilter"}],width:120,sort:"int", css:{"text-align":"right"}},
            { id:"shelf",header:["棚",{content:"selectFilter"}],width:80,sort:"int", css:{"text-align":"right"}},
            { id:"place",header:["位置",{content:"selectFilter"}],width:80,sort:"int", css:{"text-align":"right"}},
            { id:"name",header:["保管先名称",{content:"textFilter"}],width:250},
            { id:"memo",header:["メモ",{content:"textFilter"}],width:200},
            { id:"editmode",header:"editmode",width:10,hidden:true} //1:閲覧 2:更新 3:新規 4:削除
        ],

新規に追加したLC0019_print_locationlabels.phpです。

 <?php
//======================================================================
//File Name       : LC0019_print_locationlabels.php
//Encoding        : UTF-8
//Creation Date   : 2024-03-29
// 
//Copyright © 2024 sunsunfarm. All rights reserved.
// 
//This source code or any portion thereof must not be  
//reproduced or used in any manner whatsoever.
//====================================================================== 
	header("Content-Type: text/javascript; charset=utf-8");
	$myfilename = basename(__FILE__);	//自分自身のファイル名取得
	$userid = '';
	$logheader = 'userid='.$userid.', '.$myfilename.':';//ログ出力時のヘッダー情報(自ファイル名,ログインIDを付与)
	if($_SERVER["REQUEST_METHOD"] != "POST"){
	  error_log($logheader.' not POST method');
	  header("HTTP/1.0 404 Not Found");
	  return;
	}
	//指定パラメータでUPDATEする
    //POST情報からパラメータ取得
	$accesskey = 0;
	if(isset($_POST['accesskey'])){
		 if(is_numeric($_POST['accesskey'])){
			$accesskey = $_POST['accesskey'];
			$error_flag = 1;
		}
	}
	else{
		$error_flag = -1;
	  	error_log($logheader.'  accesskey not found');
	  	header("HTTP/1.0 404 Not Found");
	  	exit;
	}
	if(isset($_POST['userid'])){
		$userid = $_POST['userid'];
		$error_flag = 1;
	}
	else{
		$error_flag = -1;
	  	error_log($logheader.'  userid not found');
	  	header("HTTP/1.0 404 Not Found");
	  	exit;
	}

	$job_info = "LC0019";
	if(isset($_POST['job_info'])){
		$job_info = $_POST['job_info'];
	}

    
	$logheader = 'userid='.$userid.', '.$myfilename.':';//ログ出力時のヘッダー情報(自ファイル名,ログインIDを付与)

	include('../../commonlib/svr_common_lib_v2.php');	//
	$config_obj = get_config_obj();
	$print_mode = $config_obj::get('app01.print_mode');	//QRコード印刷モード blank:通常 test:logのみ
	$tepra_print_serve_ip = $config_obj::get('app01.tepra_print_server');	//QRコード印刷指示PCのIPアドレス
	$tepra_print_serve_port= $config_obj::get('app01.tepra_print_serve_port');	//QRコード印刷指示URLのポート番号(8081)
	//アクセスキーチェック
	if(Chk_AccessKey($accesskey)){
	}
	else{
		error_log($logheader.'  accesskey check error');
	  	header("HTTP/1.0 404 Not Found");
	  	exit;
	}
	
    $print_lists = array();
    if(isset($_POST['print_lists'])){
        $print_lists_str = $_POST['print_lists'];
        $print_lists = json_decode($print_lists_str ,true);
    }


    /**
     * curl でGET通信を行う
     *
     * @param [string] $url     - 'http://example.com/'
     * @return [string|boolean] - 成功: 取得結果,  失敗: false
     */
    function sendGetRequest($url){
      $option = [
          CURLOPT_RETURNTRANSFER => true,   // 文字列として返す
          CURLOPT_TIMEOUT        => 9000,   // タイムアウト時間
          CURLOPT_SSL_VERIFYPEER => false,  // サーバ証明書の検証をしない
      ];
      // curl初期化
      $ch = curl_init($url);
      curl_setopt_array($ch, $option);
      $body     = curl_exec($ch);
      $info     = curl_getinfo($ch);
      $errorNo  = curl_errno($ch);
      $errorMsg = curl_error($ch);
      // 「CURLE_OK」以外はエラーなのでエラー情報を返す
      if ($errorNo !== CURLE_OK) {
          // 詳しくエラーハンドリングしたい場合はerrorNoで確認
          // タイムアウトの場合はCURLE_OPERATION_TIMEDOUT
          return $errorNo . " : " . $errorMsg;
      }
      // 200以外のステータスコードは失敗なのでそのステータスコードを返す
      if ($info['http_code'] !== 200) {
          return $info['http_code'];
      }
      $responseArray = json_decode($body, true);               // JSON を配列に変換
      return($responseArray);
    }

    //
    //メインルーチン
    //
    
   	$config_obj = get_config_obj();
    //データベース接続する(MariaDB)
    $dbh = mariadb_connect($config_obj,'app01','webix-server_redmine001');
    if($dbh == false){
    	//エラー応答
    	$resp = "ng";
		$error_code = -2;
 		$json_data = json_encode(compact("resp","error_code"),JSON_UNESCAPED_UNICODE);
		echo $json_data;
		exit;
    }

  	try{
		
		$update_sql1 = "UPDATE locations SET memo = ?,updated_userid = ?,updated_on= ? where id= ?";
		$update_stmt =  $dbh->prepare($update_sql1);
		
		// 静的プレースホルダを指定
   		$dbh->setAttribute(PDO::ATTR_EMULATE_PREPARES, false);
   		// エラー発生時に例外を投げる
   		$dbh->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
	
    	//トランザクション処理を開始
    	$dbh->beginTransaction();
		$resp = "ok";
		$error_code = 0;
		
		for($i=0;$i<count($print_lists);$i++){
			//制御先のURLとパラメータ準備
			if($print_mode == ""){
				$url = 'http://'.$tepra_print_serve_ip.':'.$tepra_print_serve_port.'/?code='.$print_lists[$i]["code"].'&label='.urlencode($print_lists[$i]["name"]);
			}
			else{
				$url = 'http://'.$tepra_print_serve_ip.':'.$tepra_print_serve_port.'/?code='.$print_lists[$i]["code"].'&label='.urlencode($print_lists[$i]["name"]).'&mode='.$print_mode;
			}
			error_log($logheader.' url=:'.$url);
			//ラベル印刷
			$rs = sendGetRequest($url);
			if($rs != 0){
				error_log($logheader.'  sendGetRequest error rs='.$rs);
				$resp = "ng";
				$error_code = -10;
				$dbh = null;
				$json_data = json_encode(compact("resp","error_code"),JSON_UNESCAPED_UNICODE);
				echo $json_data;
				exit;
			}
			else{
				$memo = $print_lists[$i]["memo"];
				if($memo == ""){
					$memo = "印刷済";
				}
				else{
					$memo = $memo." 印刷済";
				}
			    $update_stmt->bindValue(1,$memo);
			    $update_stmt->bindValue(2,$userid);	//updated_userid
			    $update_stmt->bindValue(3,date("Y-m-d H:i:s"));
			    $update_stmt->bindValue(4,intval($print_lists[$i]["id"]),PDO::PARAM_INT);
			    $update_stmt->execute();
			    error_log($logheader.' update locations id=:'.$print_lists[$i]["id"]);
			}
		}
		$dbh->commit();
		$dbh = null;
		error_log($logheader.' commit');
  	} catch(PDOException $e){
		error_log($logheader.'  捕捉した例外: '.$e->getMessage());	//例外発生時の処理(エラー情報をログに格納してエラー応答)
		$resp = "ng";
		$error_code = -1;
  	}
	$dbh = null;
	$json_data = json_encode(compact("resp","error_code"),JSON_UNESCAPED_UNICODE);
	//error_log($logheader.' $json_data ='.$json_data);
	echo $json_data;
?>


この記事が気に入ったらサポートをしてみませんか?