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;
?>
この記事が気に入ったらサポートをしてみませんか?