JSON API My Warehouse、自己孊習

曎新開始2019-11-18

この蚘事はただ誰かのための情報源であるこずに気付きたした。

コヌドをより簡単にするためにリファクタリングを行いたした。 途䞭で、いく぀かの迷惑なバグを修正したした。

最終曎新日2019-11-18



テストタスクの完了など、セルフトレヌニングの方法がありたす。 その利点は、タスクのボリュヌムが有限であり、時間が制限されるこずです。 これは、無限にゎムを匕っ匵ったり、建築の喜びのひねりやカヌルを無我倢䞭で描くこずを蚱可したせん。



このようなスキルトレヌニングの玠晎らしいボヌナスは、新しいテクノロゞヌずビゞネスプロセスに粟通するこずです。これは、ずりわけ、実際のタスクで需芁がありたす。



今回は、My Warehouseサヌビスで顧客泚文を䜜成するペヌゞを䜜成する必芁がありたした。 私にずっおは、たるで月に飛んでいるようなものです。Web開発では初心者よりもやや少なく、フロント゚ンドは䌝聞だけで知っおいたすが、ここではペヌゞ党䜓を開発する必芁がありたす。

どんな批刀やアドバむスも倧歓迎です。



コメントには倚くの宣誓がありたすが、私の決定は非垞に恐ろしいため、圌のために適切なリファクタリングを行いたした。

michael_vostrikov

䜕もするこずなく、私はこのタスクのリファクタリングを少し行いたしたただし、倉曎できるものは他にもたくさんありたす。埌で怜玢でこの蚘事を芋぀けた人たちほどではありたせん。

コミット 、 マヌクアップ 、 フォヌム送信 。


行こう



もちろん、最初のこずはグヌグルです。 ドキュメント 、チュヌトリアル、䟋ぞのリンクのみがグヌグルです-れロ。



それでもグヌグル「JSON APIは、無料を陀くすべおの料金で加入者が利甚できたす」おっず もちろん、誰も私に有料のものをくれなかったし、カミヌナを買わなかったが、もし圌らが私にそのような割り圓おを䞎えたなら、おそらく䜕かが無料のもので機胜しおいお、働き続けたず思った。



そしおもちろん、「moysklad-client-npm-MySkladサヌビスAPIで快適に䜜業できるJavaScriptクラむアント」はグヌグルで怜玢されたしたが、私はJSず「あなた」だけに専念しおいたす。 そのため、JSで䜕ができるかさえ理解できたせんでした。



最初に



最初に行うこずは、ドキュメントに粟通するこずです。 䌚った。

2぀目は蚈画を立おるこずです。 コンパむル枈み。

蚈画、始たり。

最初のアクションは承認です。

2番目のアクションは、呜名法のリストを衚瀺するこずです。

ステップ3-バむダヌ泚文を远加したす。

4番目のアクションは、賌入者の泚文にアむテムを远加するこずです。

目暙は達成され、蚈画は終了したした。



ログむン



APIずの通信にcUrlが䜿甚されおいるコヌドを芋たした。 cUrlずは䜕か、APIずの通信方法はわかりたせんが、コピヌできるコヌドがあれば、その適合性を確認するのは難しくありたせん。 私はそれをコピヌし、貌り付け、ファむルで凊理したした-刀明したした。



コピヌず貌り付けによるファむルの友情に぀いおの詳现は説明したせん。ここに䜜業コヌドを瀺したす。



function setupCurl($apiSettings) { $curl = curl_init(); curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, false); curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, false); curl_setopt($curl, CURLOPT_RETURNTRANSFER, true); curl_setopt($curl, CURLOPT_FOLLOWLOCATION, false); $userName = $apiSettings[MOYSKLAD_USERNAME]; $userPassword = $apiSettings[MOYSKLAD_PASSWORD]; curl_setopt($curl, CURLOPT_USERPWD, "$userName:$userPassword"); curl_setopt($curl, CURLOPT_USERAGENT, $apiSettings[MOYSKLAD_USER_AGENT]); return $curl; }
      
      





カヌルオプション





他のオプションは、なぜそれらが必芁なのかわかりたせん、愚かなコピヌペヌスト。

最初の送信埌にリセットされなかったずいう事実ではありたせんが、承認ヘッダヌを各リク゚ストで送信する必芁があるずいう事実ではありたせん...



APIサヌバヌずのメッセヌゞングのためのcurlオブゞェクトの初期化でした。



䜿甚法



 function curlExec($curlObject) { $response = curl_exec($curlObject); $curlErrorNumber = curl_errno($curlObject); if ($curlErrorNumber) { throw new Exception(curl_error($curlObject)); } return $response; }
      
      





玔粋なコピヌアンドペヌスト、理由を聞かないでください。



アむテムのリストを衚瀺



バむダヌの泚文には、1぀のアむテムだけでは䞍十分であるこずが刀明したした。サプラむダヌずバむダヌの取匕盞手の法人を瀺す必芁がありたす。 My Warehouseアカりントの所有者は、耇数の法人、カりンタヌパヌティを持぀こずができたす-100500であるこずは明らかですが、特定の賌入者の泚文は、特定の法人に察する特定のカりンタヌパヌティの泚文です。



したがっお、呜名法を埅ち、「契玄」の圓事者である取匕を扱いたす。



法人



 $curl = setCurl( $curl, $apiSettings[MOYSKLAD_API_URL] . $apiSettings[MOYSKLAD_GET_JURIDICAL_PERSON], $apiSettings[MOYSKLAD_GET_JURIDICAL_PERSON_METHOD]); $persons = getJuridicalPerson($curl); function setCurl(&$curlObject, $uri, $method) { curl_setopt($curlObject, CURLOPT_URL, $uri); curl_setopt($curlObject, CURLOPT_HTTPGET, true); switch ($method) { case MOYSKLAD_METHOD_GET: break; case MOYSKLAD_METHOD_POST: curl_setopt($curlObject, CURLOPT_POST, true); break; case MOYSKLAD_METHOD_PUT: curl_setopt($curlObject, CURLOPT_PUT, true); break; } return $curlObject; } function getJuridicalPerson($curlObject) { $response = curlExec($curlObject); $data = json_decode($response, true); $result = $data['rows']; return $result; }
      
      





定数の恐ろしい名前をおaびしたすが、それらず混同しないように、私はそれらでよりリラックスしおいたす。 はい、ケヌススむッチにはデフォルトのブランチがあるこずは知っおいたすが、デフォルト倀をコヌドに具䜓化しお、ケヌスの䞍幞な運呜に頌らない方が快適です。



各APIコマンドには、独自のアドレスず独自のメ゜ッドsetCurlがあり、アドレスずメ゜ッドを蚭定したす。



法人のリストを取埗するには、適切なアドレスずメ゜ッドを蚭定したすアドレスずメ゜ッドは蚭定で蚭定され、蚭定は関数getSettings{$ apiConfig = include 'moysklad_curl_details.php'; return $ apiConfig;}によっおロヌドされたす。



その埌、getJuridicalPersonメ゜ッドでcurlを実行し、JSONで応答を取埗し、応答から「行」配列のみを取埗したす。 受信、保存、延期。



カりンタヌパヌティでは、同じアルゎリズムを䜿甚したすsetCurl => getCounterparty、同じアルゎリズムによる呜名法setCurl => getNomenclature。



仕事の埌の2晩のテストではなく、倱業者の2日間のテストであれば、それを自動化するこずは可胜ですが、それは「仕事するだけ」のスタむルのテストだったので、気分を害するこずはありたせんでした。



私にずっお、テストの目暙は、JSON APIをすすり、味わうこず、矎しさを匕き出すこずでした-目暙はありたせんでした。



受け取ったデヌタ-それはたったく質問ではなく、愚かなこずです-それはトリッキヌなビゞネスではありたせん。ペヌゞに持っお行っおからペヌゞからそれを拟うのがより面癜かったのです。



フロント゚ンド



私はそれを正しく行う方法がわかりたせん、私はこれをしたした



 echo '<form action="#" onsubmit="return false;" id="orderForm" ><p>  :<br />'; foreach ($persons as $key => $person) { $personId = $person['id']; echo '<label for="' . $personId . '">' . $person['name'] . '</label><input type="radio" data-organization-type="1" id="' . $personId . '" name="organization"><br />'; } echo ' :<br />'; foreach ($counterparty as $key => $person) { $personId = $person['id']; echo '<label for="' . $personId . '">' . $person['name'] . '</label><input type="radio" data-counterparty-type="1" id="' . $personId . '" name="counterparty"><br />'; } echo ' :<br />'; foreach ($nomenclature as $key => $position) { $positionId = $position['id']; echo '<label for="' . $positionId . '">' . $position['name'] . ',    => </label><input type="text" id="' . $positionId . '" data-position-type="1"><br />'; } echo ' <input type="submit" name="  " onclick="sendOrder();"><br /></p></form>'
      
      





䞀般的なアルゎリズム



  1. セクションの名前を曞きたす
  2. ポゞションの名前を曞いお、
  3. 入力タグを蚘述し、id属性にAPIから取埗した識別子を蚘述し、
  4. 属性を取埗するには倀を割り圓おる必芁があるため、察応する属性data-organization-type / data-counterparty-type / data-position-typeを蚘述したす


䞀般的に、もちろん、倀なしで属性を䜿甚できたすが、その方法はわかりたせんでした。



「顧客泚文の䜜成」ボタンをクリックするず、フォヌムは送信されたせん-「return false;」ですが、関数は「sendOrder;」ず呌ばれたす。



泚文を送信



 echo ' <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js" type="text/javascript"></script> <script type="text/javascript"> function sendOrder(){ var $text_field = $('#orderForm :input:text'); var position = {}; $text_field.each(function() { var this_val = $(this).val(); var may_assign = this_val>0 || this_val !=""; var is_it_position = $(this).data('position-type'); if ( may_assign && is_it_position > 0){ position[this.id] = this_val; } }); var $radio_field = $('#orderForm :input:radio:checked'); var counterparty = {}; var organization = {}; $radio_field.each(function() { var this_val = $(this).val(); var is_it_counterparty = $(this).data('counterparty-type'); var is_it_organization = $(this).data('organization-type'); var may_assign = this_val>0 || this_val !=""; if ( may_assign && is_it_counterparty > 0){ counterparty[this.id] = this_val; } if ( may_assign && is_it_organization > 0){ organization[this.id] = this_val; } });
      
      





C JSは私には透明以䞊のようです。



  1. $ 'orderForminputtext'; -orderForm識別子を持぀タグ内のタむプテキストを持぀すべおの入力タグを遞択したした
  2. $ text_field.each-各芁玠に察しお匿名関数を実行したす
  3. var this_val = $this.val; -保存された倀
  4. var may_assign = this_val> 0 || this_val= ""; -倀が空ではないこずを蚈算
  5. var is_it_position = $this.data 'position-type'; -data-position-type属性が蚭定されおいるず蚈算された
  6. ifmay_assign && is_it_position> 0{position [this.id] = this_val; }-倀が空ではなく、この入力が䜍眮に察応する堎合、察応する芁玠を䜍眮の配列に远加したす。むンデックスずしおの識別子は䞀意性を保蚌したす。


法人ず察抗゚ヌゞェントで同じアクロバットを行いたすが、分析では「チェック枈み」状態の「ラゞオ」タむプのすべおの入力を遞択する点が異なりたす。



$ 'orderForminputradiochecked'、さらに、input芁玠の倀は必芁ありたせん。賌入者が遞択したリスト党䜓から誰1を知る必芁があるだけです。



凊理に送信するデヌタの準備ができたので、リク゚ストを䜜成する必芁がありたす。



  var postData = JSON.stringify({position : position, counterparty : counterparty , organization : organization}); console.log(postData); $.ajax({ type: "POST", url: "moyskald_add_order.php", data: postData, contentType: "application/json; charset=utf-8", dataType: "text", timeout: 10000, error: function(){ alert("  "); }, success: function(data){alert(data);}, failure: function(errMsg) { alert(errMsg); } });
      
      





このコピヌペヌストに远加するものはありたせん。送信方法は「POST」、凊理は「moyskald_add_order.php」、デヌタは「application / json;」の圢匏で行われたす。 charset = utf-8 "、圢匏は-" text "です。



デヌタはたったく必芁ありたせんが、もちろん、「泚文が承認されたした」たたは「泚文の远加に倱敗したした」ずナヌザヌに䌝えるのが良い口調です。



次の到着点である「凊理」に進みたす。



凊理䞭



凊理で䞍発が発生したした。 私はEnameikレヌマヌであり、XAMPPWin10の䞋を開発に䜿甚しおいたす。 そしお、そのような䜕かが蚭定されおいたす。通垞の人ずしおPHPスクリプトぞのGETリク゚ストを受け取り、POSTリク゚ストは1か所でしか取埗できたせん。



ただし、GETはキャッシュされおおり、サヌバヌの応答が前回ずたったく同じになるずいう事実はありたせん。特に開発䞭の堎合、サヌバヌロゞックは5分ごずに倉曎されたす。



そのため、file_get_contents「php// input」の圢匏でブラックマゞックを䜿甚する必芁がありたした。䜕をしおも、var_export$ POSTが安定しお「array」を返したからです。 ずころで、正しい方向ぞの䞀連のキックに感謝したす。



そしお、すべおが簡単です



 $data = json_decode($rawData, true); $rawPosition = $data['position']; $rawCounterparty = $data['counterparty']; $rawOrganization = $data['organization'];
      
      





入力を解析したした。



法人ず取匕盞手が匕き出されたした



 const FIRST_INDEX = 0; $counterpartyId = $counterpartyIdCollection[FIRST_INDEX]; $organizationId = $organizationIdCollection[FIRST_INDEX];
      
      





圢成されたリク゚ストフィヌルド



 $textAddCustomerOrder = ' { "name": "' . time() . '", "organization": { "meta": { "href": "https://online.moysklad.ru/api/remap/1.1/entity/organization/' . $organizationId . '", "type": "organization", "mediaType": "application/json" } }, "agent": { "meta": { "href": "https://online.moysklad.ru/api/remap/1.1/entity/counterparty/' . $counterpartyId . '", "type": "counterparty", "mediaType": "application/json" } } } '; $apiSettings = getSettings(); $curl = setupCurl($apiSettings); $curl = setCurl( $curl, $apiSettings[MOYSKLAD_API_URL] . $apiSettings[MOYSKLAD_ADD_CUSTOMER_ORDER], $apiSettings[MOYSKLAD_ADD_CUSTOMER_ORDER_METHOD]); curl_setopt($curl, CURLOPT_POSTFIELDS, $textAddCustomerOrder); curl_setopt($curl, CURLOPT_HTTPHEADER, array( 'Content-Type: application/json', 'Content-Length: ' . strlen($textAddCustomerOrder)) );
      
      





それから、json_encodeなしでjsonがフリヌズし、愚かなこずに正しい堎所に識別子を貌り付けたこずがわかりたした。 必ずPOSTFIELDS-$ textAddCustomerOrder、HTTPHEADER-'Content-Length'を実行しおください。 strlen$ textAddCustomerOrder。



APIサヌバヌに凊理のリク゚ストを送信したす$ customerOrderId = setCustomerOrder$ curl、レスポンスで 'id'を取埗したす。



泚文が远加されたした。



バむダヌの泚文にアむテムを远加する



プランのこのアむテムを䜿甚するず、json_encodeを䜿甚しおリク゚ストテキストず、䜍眮にある商品の数量のfloatvalをフォヌマットする必芁があるこず以倖に問題はありたせん。 floatvalを䜿甚しない堎合、APIサヌバヌは数量フィヌルドおよびそれぞれ予玄フィヌルドのフォヌマット゚ラヌを生成したす。



 $isPositionArray = is_array($rawPosition); $orderPositions= array(); if ($isPositionArray) { foreach ($rawPosition as $id => $quantity) { $positionQuantity=floatval($quantity); $orderPositions[] = [ "quantity" =>$positionQuantity, "price"=>0, "discount"=>0, "vat"=>0, "assortment" =>[ "meta"=>[ "href"=>"https://online.moysklad.ru/api/remap/1.1/entity/product/$id", "type"=>"product", "mediaType"=>"application/json" ] ], "reserve"=>$positionQuantity, ]; } }
      
      





泚foreach$ rawPosition as $ id => $ quantity、䜍眮の識別子は配列のキヌに曞き蟌たれ、泚文の数量は配列の芁玠の倀に含たれたす。



私の颚氎では、各配列を個別に䜜成し、すべおの「基本」配列を䞀般的なヒヌプに远加する必芁がありたすが、...これは過床の狂信的だず思われたす。



顧客の泚文に予備金を蚭定する必芁があるかどうかはわかりたせんが、これはAPIを䜿甚する仕組みよりもビゞネス䞊の芁件であるように思われたす。



䟡栌、アむテムをリストするために必芁なタスク、私にずっおは、䟡栌は含たれおいないアむテムず察応するTTXのリストですが、考えおみるず、䟡栌はそのようなアプリケヌションの最初のTTXですが、泚文フォヌムには䟡栌がありたせん、したがっお-合栌したした。



リク゚ストAPIを送信するず、すべおが非垞に明確になりたした



 $jsonResponse = 'empty'; $isContainPosition = count($orderPositions)>0; if($isContainPosition ){ $jsonOrderPositions= json_encode($orderPositions); $curl = setupCurl($apiSettings); $curl = setCurl( $curl, $apiSettings[MOYSKLAD_API_URL] . $apiSettings[MOYSKLAD_ADD_ORDER_POSITION_PREFIX] . $customerOrderId . $apiSettings[MOYSKLAD_ADD_ORDER_POSITION_SUFFIX], $apiSettings[MOYSKLAD_ADD_ORDER_POSITION_METHOD]); curl_setopt($curl, CURLOPT_POSTFIELDS, $jsonOrderPositions); curl_setopt($curl, CURLOPT_HTTPHEADER, array( 'Content-Type: application/json', 'Content-Length: ' . strlen($jsonOrderPositions)) ); $jsonResponse = setCustomerOrderPosition($curl); }
      
      





芁求コマンドのアドレスは、やや奇劙な方法で「蚈算」されたす。

 $apiSettings[MOYSKLAD_API_URL] . $apiSettings[MOYSKLAD_ADD_ORDER_POSITION_PREFIX] . $customerOrderId . $apiSettings[MOYSKLAD_ADD_ORDER_POSITION_SUFFIX]
      
      





ドキュメントによるず、「/゚ンティティ/ customerorder / {id} /ポゞション」です。



ネむティブPHP文字列のように、それを取り、それを正しく蚘述したす-{id}を眮き換えたすが、APIコマンドの蚘述に関するハヌドコヌドを蚱可するこずはできたせん。もちろん、テストの蚘述䞭にコマンドは倉曎されたせんが、Feng Shuiはそのようなグロヌバルなものを定数に取り蟌む必芁がありたすアヌメン。 あらゆる皮類のオヌプン゜ヌスフレヌムワヌクの゜ヌスを芋るず、そこにハヌドコヌドが非垞に近いこずがわかりたすが、ハヌドコヌドはそれを実行し、実行したすが、実行したせん。



゚ピロヌグ



それだけです。 APIは、無料料金で、最埌のタヌンでリク゚ストを凊理するため、10秒のタむムアりトでは䞍十分な堎合がありたす。 残りは安定しお動䜜したす。 確認したした。

もちろん、私たちの目暙はこれではありたせんでした。割り圓おの結果、JSON Web APIを操䜜する方法を孊び、フォヌムに情報を出力し、サヌバヌスクリプトに凊理するためのナヌザヌ入力を枡すこずでフロント゚ンドをかき立おる方法を孊びたした。

やったヌ



PostScriptum



蚘事を曞く前に、「php json api my warehouse」ずいうトピックに぀いおもう少し詳しく調べおみたしたが、倚くの実装が芋぀かりたしたが、JSONではなくXMLです。 発芋されたダヌスのうち、いく぀かは実際に機胜しおいるこずに䌌おいたすが、2017幎3月31日以降、XML APIが無効になるず脅されおいるため、これは関係ありたせん。



たたは、「JSON APIは、無料を陀くすべおの料金で加入者が利甚できたす」ず同じになりたす。



建蚭的な批刀ず最高の実践ぞのリンクようこそ 私は集合的な蟲民であるこずを恥じおいたせんが、それがより良いのなら、それは良くないでしょうか



参照資料



  1. Git



All Articles