Webixライブラリを使った電子帳簿保存機能(機能改善:PDFプレビュー)(その2)No.050
前回の記事では、PDFプレビュー画面を開く動作を紹介しましたが、実際に、電子帳簿管理機能にPDFプレビュー機能を実装します。
以前の機能も残して、今回、以下の機能を追加します。
対象伝票(PDF)を選択すると、プレビュー画面で開いて、内容を確認しながら、関連情報(金額、支払い業者、日付など)を画面に設定し、格納する動作となります。
新規登録画面(初期画面)は、以下のとおりです。
画面下中央部分に、レシートPDF選択ボタンを追加しています。
関連する2つのボタン(PDFクリアと格納操作)は、disableにしています。
レシートPDF選択ボタンをクリックすると、ファイル選択ダイアログが表示されるので、事前にスキャンしているPDFファイルを選択します。
以下、選択した例です。
PDFプレビューは、拡大縮小操作が可能なので、確認しやすい大きさで表示し、レシートに記載されている内容を詳細画面に入力します。
入力が完了したら、初期状態でdisableしていたボタンが有効になっているので、格納操作ボタンをクリックします。
サーバ側では、対象伝票の重複登録有無を確認し、問題なければ、PDFファイルの格納とデータベースに関連情報を格納します。
画面は、PDFプレビュー画面を閉じて、次の操作ができる明細画面になります。
登録された情報を検索すると、一覧には、以下のように表示されます。
対象行をクリックすると、明細情報も確認できます。
同じ操作を再度実施し、同じレシートをレシートPDF選択ボタンクリック後に選択すると、以下のようなメッセージが表示され、重複登録を確認できます。
複数の伝票を登録する作業を行うとき、登録漏れがないことや、重複登録していないことが簡単に確認できると、作業品質が向上しますが、登録操作時に、対象PDFを別フォルダに移動したり、ファイル名を修正したりする操作は、ブラウザのセキュリティ面でガードされていて、該当操作はできません。もし、やりたい場合は、Javascriptではなく、PC上で動作するC#アプリなどで、実装し、サーバ側のREST APIをコールする動作で作るしかありません。いずれ、この機能も実装してみようかと思います。
一度に10枚以上の伝票を操作するには、実施有無を確認しやすい仕様にしないと、作業性が悪いと思っています。
C#のアプリでもPDFのプレビューを実装できることは確認済なので、PDFファイルのアップロード機能をどのように実装するかが、整理できたら、実装してみようと思います。
今回、実装したPDFレビューと対象伝票の格納機能は、Webixのuploader
コンポーネントを使って、UPLOAD時に電子伝票の情報を同時にサーバに転送(formDataを加える)しています。
格納操作の個別画面ソース(Javascript)の中で、今回、機能追加した部分だけ、以下に記載します。
//文書新規格納画面
var EB0013_win_resize_height=920;
var EB0013_win_resize_width=1600;
var EB0013_win_resize_top=150;
var EB0013_win_resize_left=180;
var EB0013_form_minwidth = 450;
//uploader_type:1 ファイル指定 2:PDFプレビュー
function EB0013_check_form_data(uploader_type){
var project_folder_info = $$("EB0013_project_folder").getValue();
if(project_folder_info == ""){
webix.alert("格納先のプロジェクトが未指定です。");
return false;
}
//file_typeの特定
var file_type = 0;
var EB0013_chkb1 = $$("EB0013_chkb1").getValue();
var EB0013_chkb2 = $$("EB0013_chkb2").getValue();
var EB0013_chkb3 = $$("EB0013_chkb3").getValue();
var EB0013_chkb4 = $$("EB0013_chkb4").getValue();
var EB0013_chkb5 = $$("EB0013_chkb5").getValue();
var EB0013_chkb6 = $$("EB0013_chkb6").getValue();
var EB0013_chkb7 = $$("EB0013_chkb7").getValue();
var EB0013_chkb8 = $$("EB0013_chkb8").getValue();
var EB0013_chkb9 = $$("EB0013_chkb9").getValue();
var EB0013_chkbA = $$("EB0013_chkbA").getValue();
if(EB0013_chkb1 == 1) file_type = 1;
else if(EB0013_chkb2 == 1) file_type = 2;
else if(EB0013_chkb3 == 1) file_type = 3;
else if(EB0013_chkb4 == 1) file_type = 4;
else if(EB0013_chkb5 == 1) file_type = 5;
else if(EB0013_chkb6 == 1) file_type = 6;
else if(EB0013_chkb7 == 1) file_type = 7;
else if(EB0013_chkb8 == 1) file_type = 8;
else if(EB0013_chkb9 == 1) file_type = 9;
else if(EB0013_chkbA == 1) file_type = 10;
if(file_type == 0){
webix.alert("文書種別が未指定です。");
return false;
}
var EB0013_fl_CKKNAME = $$("EB0013_fl_CKKNAME").getValue();
if(EB0013_fl_CKKNAME==""){
webix.alert("業者コードが正しく指定されていません。<br>(業者名が空欄です。)");
return false;
}
var price = $$("price").getValue();
if(price === ""){
webix.alert("金額(税抜)が空欄です。<br>(対象外なら0を記入)");
return false;
}
var taxedprice = $$("taxedprice").getValue();
var tax_rate = Number($$("EB0013_tax_rate").getValue());
if(tax_rate > 0){
tax_rate = tax_rate/100;
//税込金額が空欄なら、税率に応じて、税込額を計算して保存
var n_price = Number(price);
var n_price_with_tax = Math.round(n_price * (1+tax_rate));
$$("taxedprice").setValue(String(n_price_with_tax ));
}
else{
$$("taxedprice").setValue(price);
}
if(uploader_type == 1){
var file_count = 0;
var cnv_flag = 0;
$$("EB0013_uploder").files.data.each(function(obj,index){
if (obj.status == "client"){
upload_filename = obj.name;
if(upload_filename.indexOf(' ') > -1){
obj.name = upload_filename.replace(/ /g, '');
upload_filename = obj.name;
//file_count = -1;
cnv_flag = 1;
}
var data_lists = $$("EB0013_form2").getValues();
var memo = $$("memo").getValue();
var import_date = Number(moment($$("EB0013_importdate").getValue()).format('YYYYMMDD'));
var apply_date = Number(moment($$("EB0013_applydate").getValue()).format('YYYYMMDD'));
obj.formData = { upload_filename:upload_filename ,project_folder_info:project_folder_info,file_type:file_type,
data_lists:JSON.stringify(data_lists),memo:memo,import_date:import_date,apply_date:apply_date,
userid:my_local_session.userid ,username:my_local_session.username,file_count:file_count};
file_count += 1;
}
});
if(file_count == 0){
webix.alert("格納文書が指定されていません。");
return false;
}
else if(file_count == -1 || cnv_flag == 1){
//$$("EB0013_uploder").setValue("");
//$$("mylist").clearAll();
webix.alert("格納文書に空白が含まれています。カットしました。");
//return;
}
}
else{
var cnv_flag = 0;
upload_filename = $$("EB0013_pdf_filename").getValue();
if(upload_filename.indexOf(' ') > -1){
upload_filename = upload_filename.replace(/ /g, '');
$$("EB0013_pdf_filename").setValue(upload_filename);
cnv_flag = 1;
}
if(cnv_flag == 1){
webix.alert("格納文書に空白が含まれています。カットしました。");
}
}
return true;
}
EB0013_win = webix.ui({
view:"window",
id: "EB0013_win",
move:true,
resize:true,
height : EB0013_win_resize_height,
width : EB0013_win_resize_width,
top : EB0013_win_resize_top,
left : EB0013_win_resize_left,
head:{
cols:[
{template:"電子帳簿文書格納(EB0013)", type:"header", borderless:true}
]
},
body:{
rows:[
{view:"form",
id:"EB0013_form2",
rules:EB0013_rules,
rows: [
{view:"form",
id:"EB0013_form3",
rows: [
{margin:5, cols:[
{view:"uploader", id:"EB0013_uploader1",name:"EB0013_uploader1", width:150, value:"レシートPDF選択",
accept:"application/pdf",
autosend:false,
multiple:false,
upload:"<?php echo SUB_FOLDER; ?>/rest_api/UP1020/UP1020_upload_action.php",
on:{
onBeforeFileAdd:function(upload){
//file_typeの特定
var file_type = 0;
var EB0013_chkb1 = $$("EB0013_chkb1").getValue();
var EB0013_chkb2 = $$("EB0013_chkb2").getValue();
var EB0013_chkb3 = $$("EB0013_chkb3").getValue();
var EB0013_chkb4 = $$("EB0013_chkb4").getValue();
var EB0013_chkb5 = $$("EB0013_chkb5").getValue();
var EB0013_chkb6 = $$("EB0013_chkb6").getValue();
var EB0013_chkb7 = $$("EB0013_chkb7").getValue();
var EB0013_chkb8 = $$("EB0013_chkb8").getValue();
var EB0013_chkb9 = $$("EB0013_chkb9").getValue();
var EB0013_chkbA = $$("EB0013_chkbA").getValue();
if(EB0013_chkb1 == 1) file_type = 1;
else if(EB0013_chkb2 == 1) file_type = 2;
else if(EB0013_chkb3 == 1) file_type = 3;
else if(EB0013_chkb4 == 1) file_type = 4;
else if(EB0013_chkb5 == 1) file_type = 5;
else if(EB0013_chkb6 == 1) file_type = 6;
else if(EB0013_chkb7 == 1) file_type = 7;
else if(EB0013_chkb8 == 1) file_type = 8;
else if(EB0013_chkb9 == 1) file_type = 9;
else if(EB0013_chkbA == 1) file_type = 10;
if(file_type == 0){
file_type = 8;
$$("EB0013_chkb8").setValue(1);
}
var project_folder_info = $$("EB0013_project_folder").getValue();
if(project_folder_info == ""){
webix.alert("格納先のプロジェクトが未指定です。");
return false;
}
var access_key = Get_AccessKey();
var send_prm = Prepare_send_prm(my_local_session,access_key);
var file_name = upload.name;
var import_date = Number(moment($$("EB0013_importdate").getValue()).format('YYYYMMDD'));
var apply_date = Number(moment($$("EB0013_applydate").getValue()).format('YYYYMMDD'));
send_prm.file_name = file_name;
send_prm.project_folder_info = project_folder_info;
send_prm.import_date = import_date;
send_prm.apply_date = apply_date;
send_prm.file_type = file_type;
var xhr =webix.ajax().sync().get("<?php echo SUB_FOLDER; ?>/rest_api/EB0010/EB0014_ebooklists_db_select.php", send_prm);
var resp = JSON.parse(xhr.responseText);
if(resp.resp =="ok"){
if(resp.count == 1){
webix.alert("指定ファイル:"+upload.name+"は既に、別の案件で登録済です。ファイル名を変更して選択してください。");
return false;
}
}
else{
webix.alert("指定ファイルの格納状態チェックでエラーが発生しました。");
return false;
}
$$("EB0013_uploder").disable();
$$("EB0013_pdfWin").show();
$$("EB0013_pdf").parse(upload.file);
$$("EB0013_pdf_filename").setValue(upload.name);
$$("EB0013_upload_exe_btn2").enable();
$$("EB0013_pdf_clear_btn").enable();
}
}
},
{view:"button", width:150, value:"PDFクリア", id:"EB0013_pdf_clear_btn", name:"EB0013_pdf_clear_btn",
click:function(){
$$("EB0013_pdf").clear();
$$("EB0013_pdf_filename").setValue("");
$$("EB0013_pdfWin").hide();
$$("EB0013_uploder").enable();
$$("EB0013_upload_exe_btn2").disable();
$$("EB0013_pdf_clear_btn").disable();
}
},
{ view: "button", label: "格納操作", width:150, css:"webix_danger",id:"EB0013_upload_exe_btn2",name:"EB0013_upload_exe_btn2",
click: function() {
if(!EB0013_check_form_data(2)){ ////uploader_type:1 ファイル指定 2:PDFプレビュー
return;
}
var pdf_filename = $$("EB0013_pdf_filename").getValue();
$$("EB0013_uploader1").files.data.each(function(obj){
var access_key = Get_AccessKey();
var project_folder_info = $$("EB0013_project_folder").getValue();
//file_typeの特定
var file_type = 0;
var EB0013_chkb1 = $$("EB0013_chkb1").getValue();
var EB0013_chkb2 = $$("EB0013_chkb2").getValue();
var EB0013_chkb3 = $$("EB0013_chkb3").getValue();
var EB0013_chkb4 = $$("EB0013_chkb4").getValue();
var EB0013_chkb5 = $$("EB0013_chkb5").getValue();
var EB0013_chkb6 = $$("EB0013_chkb6").getValue();
var EB0013_chkb7 = $$("EB0013_chkb7").getValue();
var EB0013_chkb8 = $$("EB0013_chkb8").getValue();
var EB0013_chkb9 = $$("EB0013_chkb9").getValue();
var EB0013_chkbA = $$("EB0013_chkbA").getValue();
if(EB0013_chkb1 == 1) file_type = 1;
else if(EB0013_chkb2 == 1) file_type = 2;
else if(EB0013_chkb3 == 1) file_type = 3;
else if(EB0013_chkb4 == 1) file_type = 4;
else if(EB0013_chkb5 == 1) file_type = 5;
else if(EB0013_chkb6 == 1) file_type = 6;
else if(EB0013_chkb7 == 1) file_type = 7;
else if(EB0013_chkb8 == 1) file_type = 8;
else if(EB0013_chkb9 == 1) file_type = 9;
else if(EB0013_chkbA == 1) file_type = 10;
if(file_type == 0){
file_type = 8;
$$("EB0013_chkb8").getValue(1);
}
var data_lists = $$("EB0013_form2").getValues();
var memo = $$("memo").getValue();
var import_date = Number(moment($$("EB0013_importdate").getValue()).format('YYYYMMDD'));
var apply_date = Number(moment($$("EB0013_applydate").getValue()).format('YYYYMMDD'));
obj.formData = { upload_filename:upload_filename ,project_folder_info:project_folder_info,file_type:file_type,
data_lists:JSON.stringify(data_lists),memo:memo,import_date:import_date,apply_date:apply_date,
userid:my_local_session.userid ,username:my_local_session.username,file_count:1};
$$("EB0013_uploader1").send(function(response){
if(response){
if(response.status == "server"){
$$("EB0013_pdf").clear();
$$("EB0013_pdf_filename").setValue("");
$$("EB0013_upload_exe_btn2").disable();
$$("EB0013_pdf_clear_btn").disable();
$$("EB0013_pdfWin").hide();
webix.alert(upload_filename+"の格納操作が完了しました。<br>別文書を再度、格納する場合は、格納文書の選択から実施してください。");
$$("EB0013_uploder").enable();
}
else{
webix.alert(upload_filename+"の格納操作に失敗しました。");
}
}
else{
webix.alert("文書のアップロードに失敗しました。");
}
});
});
}
},
{view:"button", value: "閉じる", align:"right" , width: 150,css:"menu",
click:function(){
$$("EB0013_upload_exe_btn").disable();
webix.alert("新たに格納した文書は、再度、検索しないと一覧には未反映です。");
EB0013_win.hide();
}
}
]
},
{margin:5, cols:[
{view:"label", label:"",width:150},
{ view:"list", id:"mylist", type:"uploader",width:500,
autoheight:true
}
]},
]
}
]
},
});
webix.ui({
view:"window",
id:'EB0013_pdfWin',
body: {rows:[
{ view:"pdfbar", id:"EB0013_toolbar" },
{ view:"pdfviewer", id:"EB0013_pdf", toolbar:"EB0013_toolbar"},
{ view:"text",id:"EB0013_pdf_filename",name:"EB0013_pdf_filename",label:"pdf_filename" ,labelWidth:120, width: 230,hidden:true},
]},
head:{ view:"toolbar", cols:[
{ view:"label", label: "レシート・領収書" },
{ view:"button", label: '閉じる',
click:function(){
$$("EB0013_pdf_filename").setValue("");
$$("EB0013_pdf").clear();
$$("EB0013_pdf_filename").setValue("");
$$("EB0013_uploder").enable();
$$("EB0013_upload_exe_btn2").disable();
$$("EB0013_pdf_clear_btn").disable();
$$('EB0013_pdfWin').hide();
}
},
]
},
top:120,
left:50,
width:500,
height:800,
move:true
});
今回のPDFプレビュー機能と格納動作を連携させることで、PDFの伝票を参照しながら必要事項を画面に入力できることで、入力ミスを低減できます。
電子帳簿保存システムへの応用例を紹介させてもらいました。
興味などある方で、実際に実装や運用してみたい方は、コメントなどでお問合せください。