<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE chapter SYSTEM "gnc-gui-ja.dtd">
<!-- (Do not remove this comment block.)
Version: 2.4.0
Last modified: 2011-01-01
Maintainers:
Author:
Mike Evans <mikee@saxicola.co.uk>
Translators:
(translators put your name and email here)
-->
<!-- Todo: Database backends offer read access;
           Guile is also a sripting language perhaps its stand alone use should be explained here, too? -->
<!-- Todo: after adding a procedure convert this page into a https://tdg.docbook.org/tdg/4.5/task.html -->
<chapter id="ch_python_bindigs">
  <title>Python拡張</title>

  <para>&app;には歴史があり、財務データを扱うためにはウィンドウを開いて、操作し、保存し、閉じる必要があるという意味では伝統的なアプリケーションです。
    ウィンドウ、メニュー、およびツールバーで行えることには本質的に限界があります。
  </para>

  <para>もう少し柔軟性が必要な場合があるかもしれません。
    例えば、組み込み帳票が提供する情報と少し異なっているだけの帳票が必要な場合、または頻繁に行う作業を自動化したい場合などです。
    そのようなカスタム操作は、スクリプト言語を書く理想的な候補です。
  </para>

  <para>&app;バージョン2.4
    からは財務データを操作するために<ulink url="&url-wp-en;Python_(programming_language)">&app-py;</ulink>スクリプトを書くことができるようになりました。
  </para>

  <important>
    <para>&app-py;拡張はソースコードでのオプション機能です。
      &app-py;スクリプトを有効にするためには、&app-py;拡張を有効にして&app;をコンパイルしなければいけません。そうでない場合は動作しません。
      現在のところこのオプションはデフォルトで無効です。必要な場合は&app;を自力でコンパイルしなければいけないかもしれません。
    </para>
  </important>

  <para>&app-py;拡張を使用するためには二つの準備ができていなければいけません。
    本章ではどのように使用するかについて説明します。
  </para>

  <tip>
    <para>本章ではどのように&app-py;スクリプトを書くかに関しては説明しません。
      代わりに開発者向け文書を参照してください。
    </para>
  </tip>

  <sect1 id="python-import-invoices">
    <title>得意先請求書または仕入先請求書のインポート</title>

    <para>インポートを動作させるには、データが固定フィールド、コンマ区切りのデータでなければいけません。
      ダウンロードした注文を変換する&app-py;スクリプト例を次に示します。
    </para>

    <para><programlisting language="python" linenumbering="unnumbered">
import sys
import csv

VENDOR_ID="000013"
INFILE=sys.argv[1]
INV_ID=sys.argv[2]
try:
  ACCOUNT=sys.argv[3]
except:
  ACCOUNT="Expenses:Materials General"

Reader = csv.reader(open(INFILE), delimiter=',')

# Need to ignore 1st and last rows

for row in Reader:
  if row[0].isdigit(): # We only use numbered lines
    outline=(INV_ID + ",," + VENDOR_ID + ",,,," + row[1] + " &gt; " + row[4] + ",ea," +
      ACCOUNT + "," + row[2] + "," + row[5].replace("GBP", "") + ",,,,no,,,,,,,,")
  print outline
      </programlisting>
    </para>

    <para><emphasis>Rapid Electronics</emphasis> (UK)
      からダウンロードした仕入先注文の例は次のようになります。
<programlisting language="python" linenumbering="unnumbered">
line number,product code,quantity,availability,product description,unit price,discounts,line total,delivery,sub total,vat,grand total
1,47-3524,100,100 Available,BC848C SOT-23 NPN TRANSISTOR (INF) (RC),GBP0.03,GBP0.00,GBP0.03
2,47-3278,30,30 Available,L78L05ACZ 0.1A +5V VOLTAGE REG (ST) (RC),GBP0.18,GBP0.00,GBP0.18
3,22-0120,1,1 Available,Tube 34 14pin DIL socket, narrow7.62mm, without central support,GBP1.05,GBP0.00,GBP1.05
4,22-0127,1,0 Available&lt;br /&gt;1 on Back Order,Tube 17 28pin DIL socket, wide15.24mm, without central support,GBP1.22,GBP0.00,GBP1.22
5,62-0368,1,1 Available,820R CR25 0.25W CF Resistor Pk 100,GBP0.50,GBP0.00,GBP0.50
6,47-3130,100,100 Available,1N4001 1A 50V SILICON RECTIFIER DIODE RC,GBP0.01,GBP0.00,GBP0.01
7,17-0310,1,1 Available,PROFESSIONAL MINATURE PROBE HOOK RED RC,GBP0.90,GBP0.00,GBP0.90
8,17-0312,1,1 Available,PROFESSIONAL MINATURE PROBE HOOK BLACKRC,GBP0.90,GBP0.00,GBP0.90
9,34-0655,1,1 Available,PROTOBLOC 2 BREADBOARD,GBP4.39,GBP0.00,GBP4.39
10,18-0200,1,1 Available,PP3 9V ALKALINE BATTERY "Not For Retail Sale",GBP1.37,GBP0.00,GBP1.37
,,,,,,,,GBP4.95,GBP24.93,GBP4.35,GBP29.28
      </programlisting>
    </para>

    <para>&app-py;スクリプトで処理した後の同じファイルは次のようになります。
    </para>

    <para><programlisting language="python">
MEC-0071,,000013,,,,34-0655 &gt; PROTOBLOC 2 BREADBOARD,ea,Expenses:Materials General,1,4.39,,,,no,,,,,,,,
MEC-0071,,000013,,,,18-0105 &gt; PP3 / PP6 BATTERY CLIP 150MM (RC),ea,Expenses:Materials General,10,0.06,,,,no,,,,,,,,
MEC-0071,,000013,,,,62-0370 &gt; 1k CR25 0.25W CF Resistor Pk 100,ea,Expenses:Materials General,1,0.50,,,,no,,,,,,,,
MEC-0071,,000013,,,,62-0354 &gt; 220R CR25 0.25W CF Resistor Pk 100,ea,Expenses:Materials General,1,0.50,,,,no,,,,,,,,
MEC-0071,,000013,,,,34-5548 &gt; PLAIN DOCUMENT WALLET ASSORTED PK 50 RE,ea,Expenses:Materials General,1,6.95,,,,no,,,,,,,,
MEC-0071,,000013,,,,62-0386 &gt; 4k7 CR25 0.25W CF Resistor Pk 100,ea,Expenses:Materials General,1,0.50,,,,no,,,,,,,,
MEC-0071,,000013,,,,34-0860 &gt; COPPER CLAD SRBP SS 100 X 160 (RC),ea,Expenses:Materials General,5,0.50,,,,no,,,,,,,,
MEC-0071,,000013,,,,18-0163 &gt; PP3 BATTERY HOLDER WITH FLYING LEADS RC,ea,Expenses:Materials General,5,0.23,,,,no,,,,,,,,
MEC-0071,,000013,,,,73-4290 &gt; ATMEGA8-16PU 8-BIT MICRO 8K DIL-28 (RC),ea,Expenses:Materials General,3,1.99,,,,no,,,,,,,,
MEC-0071,,000013,,,,81-0014 &gt; BC108 NPN GP TRANSISTOR RC,ea,Expenses:Materials General,20,0.16,,,,no,,,,,,,,
MEC-0071,,000013,,,,DELIVERY,ea,Expenses:Postage,1,4.95,,,,no,,,,,,,,
MEC-0071,,000013,,,,VAT,tax,Expenses:VAT,1,4.35,,,,no,,,,,,,,
        </programlisting>
    </para>

    <para>見て分かる通りいくつかのフィールドは空白で、いくつかのフィールドはインポートには必要ありません。
      最初の行は不要です。また、&app;が注文金額を合計するので最後の行も余計です。
      必要なのは、欲しい項目を選択して&app;にインポートできる正しい形式で出力ファイルを生成することです。
      この場合、パーツ番号と説明文列を連結して&app;得意先請求書/仕入先請求書の説明欄に入力します。
      また、数量と単価の列も必要です。
      反対に<acronym>VAT</acronym>(付加価値税)列は含まれず、常に0になっています。<acronym>VAT</acronym>は最後の行で注文の合計金額に対して計算しています。
      <note>
        <para>これは後々問題の原因となります。
        </para>
      </note>
      この例では、資金移動勘定科目として<emphasis>費用:一般部材</emphasis>勘定科目を割り当てています。
      勘定科目や他のデータはインポート後に通常の方法で変更することができます。
      <emphasis>費用:一般部材</emphasis>勘定科目が無い場合は、フィールドを空にしておき、インポート時に手動で設定します。
      <quote>#</quote>で始まる行はコメントとして無視されます。
    </para>

    <para>スクリプトは次のコマンドで呼び出します。
    </para>

    <para><command>python importer.py <replaceable>file_to_import</replaceable>,
      <replaceable>invoice_id</replaceable> &gt;
      <replaceable>file_to_save_as.csv</replaceable></command>
    </para>

    <para>この短いスクリプトはダウンロード形式に合わせて容易に変更できます。
      今のところ残っている唯一の制限はフィールド数が固定ということです。
      インポートツールはフィールド数に誤りがある行を無視します。
      (将来のバージョンでは修正されます)
      VENDOR_IDは仕入先を特定するために割り当てるIDです。 raw[N]
      項は行内のデータがあるフィールド位置を表します。
      最初のフィールドがraw[1]ではなくraw[0]であることに注意が必要です。
    </para>

    <para>ファイルの変換が完了したら、
      <menuchoice>
        <guimenu>ビジネス</guimenu>
        <guimenuitem>得意先請求書&amp;仕入先請求書のインポート</guimenuitem>
      </menuchoice>
      を選択し、新規インポートウィンドウを開きます。
      作成したファイルを選択し、<guilabel>仕入先請求書</guilabel>または<guilabel>得意先請求書</guilabel>を選択します。そして<guilabel>コンマ(,)区切り</guilabel>形式を選択します。
      この時点でデータを確認するウィンドウが表示されます。
      <guibutton>OK</guibutton>を選択する前に、正しい列にフィールドデータがあることを確認します。
      いったんインポートしたら、請求書は通常通編集し、記帳することができます。
    </para>

    <para><acronym>VAT</acronym>(付加価値税)、その他の購入時にかかる税金
      (日本の場合は消費税) に関して注意が必要です。
      前に説明した<emphasis>Rapid
      Electronics</emphasis>は仕入先請求書総額に対して<acronym>VAT</acronym>を計算しています。
      一方、&app;では、行の合計ごとに<acronym>VAT</acronym>を計算し、<acronym>VAT</acronym>の金額を合計しています。
      これにより、<acronym>VAT</acronym>の金額に数セントの不整合が生じ、購入に使用した銀行またはクレジットカード勘定科目を照合する時に問題が発生する場合があります。
      差し当たり、それをどう克服するかについては、個人の良心と会計方法に依存します。
      <acronym>VAT</acronym>を別の行に、配送料と併せて手動で入力する人もいます。
      利用者にとっていくつかの作業が残りますが、すべての行を入力するつまらない作業は省くことができます。
    </para>

    <para>今後の課題:
      現在、インポート形式は非常に制限されており、多くの利用者にとって変換方法に課題があります。
      すべての業者の<acronym>CSV</acronym>形式に関するテンプレートを加えることは大きすぎて不可能な作業です。また、業者は&app;チームに連絡しないで形式を変更します。
      今後のインポート機能拡張は利用者からのフィードバックに基づきます。うまくいけば、処理をより簡単であるか、または、より柔軟にすることができます。
      しばしば、<quote>簡単</quote>と<quote>柔軟</quote>は両立しないことに注意します。
    </para>

    <note>
      <para>&app-py; (または他の利用可能な言語)
        が分からない場合、<ulink
url="&url-mail-li;gnucash-user"><citetitle>&appname;利用者メーリングリスト</citetitle></ulink>にダウンロードした<acronym>CSV</acronym>の例と併せて要望を投稿してください。誰かが変換用の&app-py;スクリプトを書いてくれるかもしれません。
      </para>
    </note>

    <sect2 id="python-author-notes">
      <title>&app-py;作者への備考</title>

      <para>インポートを成功させるには、フィールド数を守らなければいけません。よって行末にあるコンマの数も重要です。
      </para>

      <para>必須フィールドの全リストは次の通りです。
      </para>

      <para>id, date_opened, owner_id, billingid, notes, date, desc, action, account, quantity, price,
        disc_type, disc_how, discount, taxable, taxincluded, tax_table, date_posted, due_date,
        account_posted, memo_posted, accu_splits,
      </para>

      <note>
        <para>行末のコンマに注意してください。
        </para>
      </note>
    </sect2>

    <sect2 id="python-import-fields">
      <title>それぞれのフィールドの簡単な説明</title>

      <itemizedlist>
        <listitem>
          <para><emphasis>id</emphasis> - 得意先/仕入先請求書番号です。
            すべての行がこれを含まなければいけません。さもなければ、行は拒絶されます。
          </para>
        </listitem>

        <listitem>
          <para><emphasis>date_opened</emphasis> - 空欄の場合、今日の日付が使用されます。
          </para>
        </listitem>

        <listitem>
          <para><emphasis>owner_id</emphasis> - 得意先または仕入先のID番号です。
            すべての行がこれを含まなければいけません。さもなければ、行は拒絶されます。
          </para>
        </listitem>

        <listitem>
          <para><emphasis>billingid</emphasis> - 請求IDです。
          </para>
        </listitem>

        <listitem>
          <para><emphasis>notes</emphasis> - 請求書の備考です。
          </para>
        </listitem>

        <listitem>
          <para><emphasis>date</emphasis> - 項目行の日付です。
            空欄の場合、今日の日付が使用されます。
          </para>
        </listitem>

        <listitem>
          <para><emphasis>desc</emphasis> - 通常の得意先/仕入先請求書の説明です。
          </para>
        </listitem>

        <listitem>
          <para><emphasis>action</emphasis> - 仕入先請求書では、通常<quote>ea</quote>にします。
          </para>
        </listitem>

        <listitem>
          <para><emphasis>account</emphasis> - 商品の資金移動勘定科目です。
          </para>
        </listitem>

        <listitem>
          <para><emphasis>quantity</emphasis> - 商品の数量です。
            すべての行がこれを含まなければいけません。さもなければ、行は拒絶されます。
          </para>
        </listitem>

        <listitem>
          <para><emphasis>price</emphasis> - 商品の単価です。
            すべての行がこれを含まなければいけません。さもなければ、行は拒絶されます。
          </para>
        </listitem>

        <listitem>
          <para><emphasis>disc_type</emphasis> -
            値引のタイプです。<quote>%</quote>または<quote>TODO</quote>で指定します。得意先請求書にのみ当てはまります。
            実験では、通貨によってはこのフィールドが必要になります。
          </para>
        </listitem>

        <listitem>
          <para><emphasis>disc_how</emphasis> - 得意先請求書にのみ適用されます。
          </para>
        </listitem>

        <listitem>
          <para><emphasis>discount</emphasis> -
            適用する割引の量です。得意先請求書にのみ適用されます。
          </para>
        </listitem>

        <listitem>
          <para><emphasis>taxable</emphasis> -
            商品に税金を適用するかどうかを指定します。<quote>y</quote>または空欄にします。
          </para>
        </listitem>

        <listitem>
          <para><emphasis>taxincluded</emphasis> -
            商品価格に税金が含まれているかどうかを指定します。<quote>y</quote>または空欄にします。
          </para>
        </listitem>

        <listitem>
          <para><emphasis>tax_table</emphasis> - 商品に適用する税額表を指定します。
          </para>
        </listitem>

        <listitem>
          <para><emphasis>date_posted</emphasis> - 記帳する場合、記帳日を指定します。
            通常は空欄のままにし、請求書を編集した後に手動で記帳します。
          </para>
        </listitem>

        <listitem>
          <para><emphasis>due_date</emphasis> - 支払期日を指定します。
          </para>
        </listitem>

        <listitem>
          <para><emphasis>account_posted</emphasis> - 記帳先勘定科目を指定します。
          </para>
        </listitem>

        <listitem>
          <para><emphasis>memo_posted</emphasis> - 記帳する場合には、説明を指定します。
          </para>
        </listitem>

        <listitem>
          <para><emphasis>accu_splits</emphasis> -
            スプリットを累計するかどうかを指定します。<quote>y</quote>または空欄にします。
          </para>
        </listitem>
      </itemizedlist>
    </sect2>
  </sect1>
</chapter>
