<?php
namespace Plugin\Movement;
use Eccube\Entity\Order;
use Eccube\Entity\OrderDetail;
use Eccube\Entity\Product;
use Eccube\Entity\ProductClass;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Symfony\Component\EventDispatcher\GenericEvent;
use Symfony\Component\Workflow\Event\TransitionEvent;
use Plugin\Movement\LogManager;
class Event implements EventSubscriberInterface
{
private $url = 'https://webapi.smaregi.jp/access/';
private $contractId = 'skcc222y1';
private $token = '4b5ad52adf4c8dec3e49457ff56884f8';
/**
* @return array
*/
public static function getSubscribedEvents()
{
return [
'admin.product.edit.complete' => 'onAdminProductEditComplete',
'front.shopping.complete.initialize' => 'onFrontShoppingCompleteInitialize',
'admin.order.edit.index.complete' => 'onAdminOrderEditIndexComplete',
'workflow.order.transition.cancel' => 'onWorkflowOrderTransitionCancel',
];
}
public function onAdminProductEditComplete(GenericEvent $event)
{
//error_log( date('[Y-m-d H:i:s] ') . 'onAdminProductEditComplete' . "\n", 3, "/home/liquor-sato/temp/log.txt");
/** @var Product $product */
$product = $event->getArgument('Product');
/** @var ProductClass $productClass */
$productClass = $product->getProductClasses()[0];
$stock = $productClass->getStock();
$stockUnlimited = $productClass->isStockUnlimited();
$code = $productClass->getCode();
$logManager = LogManager::sharedInstance();
if (empty($code)) {
$logManager->logOutward("管理画面編集終了時の処理を開始します。商品IDがありませんでした。処理を行いません。", 'admin_edit_complete_start');
} else if ($stockUnlimited === true) {
$logManager->logOutward("管理画面編集終了時の処理を開始します。商品ID: {$code} の商品を、在庫無制限により在庫の操作をしません。", 'admin_edit_complete_start');
// 以下、以前はそのような仕様があったが、いまはしなくてよいよう
//$logManager->logOutward("管理画面編集終了時の処理を開始します。商品ID: {$code} の商品を、在庫: 0 (無制限により) に変更します。", 'admin_edit_complete_start');
//$this->sendRequest(0, $code);
} else if ((string)$stock !== '0' and empty($stock)) {
$logManager->logOutward("管理画面編集終了時の処理を開始します。在庫の数値を確認できませんでした。処理を行いません。", 'admin_edit_complete_start');
} else {
$logManager->logOutward("管理画面編集終了時の処理を開始します。商品ID: {$code} の商品を、在庫: {$stock} に変更します。", 'admin_edit_complete_start');
$this->sendRequest($stock, $code);
}
//error_log( date('[Y-m-d H:i:s] ') . 'Code: ' . $code . ' Stock: ' . $stock . "\n", 3, "/home/liquor-sato/temp/log.txt");
}
public function onAdminOrderEditIndexComplete(GenericEvent $event)
{
$argumentKey = 'TargetOrder';
$order = $event->getArgument($argumentKey);
$this->onUpdateOrder($order, 'admin_order_edit');
}
public function onFrontShoppingCompleteInitialize(GenericEvent $event)
{
$argumentKey = 'Order';
$order = $event->getArgument($argumentKey);
$this->onUpdateOrder($order, 'shopping_complete');
}
public function onWorkflowOrderTransitionCancel(TransitionEvent $event)
{
$order = $event->getSubject()->getOrder();
$this->onUpdateOrder($order, 'workflow_order_cancel');
}
private function onUpdateOrder(Order $order, $type)
{
//error_log( date('[Y-m-d H:i:s] ') . 'xxxxxx' . "\n", 3, "/home/liquor-sato/temp/log.txt");
$action = '';
$actionCode = '';
switch($type){
case 'shopping_complete':
$action = '商品購入完了時の処理';
$actionCode = 'shopping_complete';
break;
case 'admin_order_edit':
$action = '注文編集時の処理';
$actionCode = 'order_edit_complete';
break;
case 'workflow_order_cancel':
$action = '注文キャンセル時の処理';
$actionCode = 'workflow_order_cancel';
break;
}
$logManager = LogManager::sharedInstance();
$logManager->logOutward($action . "を開始します。", $actionCode . '_start');
//$arguments = $event->getArguments();
//$keys = array_keys($arguments);
/*
//$orderDetails = $order->getOrderDetails();
$orderDetails = $order->getOrderItems();
$orderData = array(
'orderId' => $order->getId(),
'subTotal' => $order->getSubtotal() - $order->getTax(),
'discount' => $order->getDiscount(),
'deliveryFee' => $order->getDeliveryFeeTotal(),
'charge' => $order->getCharge(),
'tax' => $order->getTax(),
'totalPrice' => $order->getTotalPrice()
);
*/
$detailArray = array();
$orderItems = $order->getOrderItems();
foreach ($orderItems as $orderItem) {
/** @var ProductClass $productClass */
$productClass = $orderItem->getProductClass();
$product = $orderItem->getProduct();
if (empty($productClass)) {
continue;
}
$stock = $productClass->getStock();
$stockUnlimited = $productClass->isStockUnlimited();
$code = $productClass->getCode();
/*
$transactionDetail = array(
'code' => $orderItem->getProductCode(),
'name' => $orderItem->getProductName(),
'price' => $orderItem->getPrice(),
'quantity' => $orderItem->getQuantity(),
);
$detailArray[] = $transactionDetail;
*/
if (empty($code)) {
$logManager->logOutward("商品IDがありませんでした。処理を行いません。", $actionCode . '_doing');
} else {
switch($actionCode) {
case 'shopping_complete':
if ($stockUnlimited === true) {
// unlimitedの場合在庫の相対値操作
$difference = $orderItem->getQuantity() * -1;
$logManager->logOutward("商品ID: {$code} の商品を、在庫: " . $difference . " (無制限により) します。", $actionCode . '_doing');
$this->sendRequest($difference, $code, 2);
} else {
// unlimitedでないなら新しい在庫の数値に合わせる
if ((string)$stock !== '0' and empty($stock)) {
$logManager->logOutward("商品ID: {$code} の商品について、在庫の数値を確認できませんでした。処理を行いません。", $actionCode . '_doing');
} else {
$logManager->logOutward("商品ID: {$code} の商品を、在庫: {$stock} に変更します。", $actionCode . '_doing');
$this->sendRequest($stock, $code);
}
}
break;
case 'order_edit_complete':
if ($stockUnlimited === true) {
$logManager->logOutward("商品ID: {$code} の商品について、無制限のため、この部分では処理を行いません。", $actionCode . '_doing');
} else {
// unlimitedでないなら新しい在庫の数値に合わせる
if ((string)$stock !== '0' and empty($stock)) {
$logManager->logOutward("商品ID: {$code} の商品について、在庫の数値を確認できませんでした。処理を行いません。", $actionCode . '_doing');
} else {
$logManager->logOutward("商品ID: {$code} の商品を、在庫: {$stock} に変更します。", $actionCode . '_doing');
$this->sendRequest($stock, $code);
}
}
break;
case 'workflow_order_cancel':
if ($stockUnlimited === true) {
// unlimitedの場合在庫の相対値操作
$difference = $orderItem->getQuantity();
$logManager->logOutward("商品ID: {$code} の商品を、在庫: +" . $difference . " (無制限商品のキャンセルにより) します。", $actionCode . '_doing');
$this->sendRequest($difference, $code, 2);
} else {
//$logManager->logOutward("商品ID: {$code} の商品について、無制限ではないため、この部分では処理を行いません。", $actionCode . '_doing');
// unlimitedでないなら新しい在庫の数値に合わせる
if ((string)$stock !== '0' and empty($stock)) {
$logManager->logOutward("商品ID: {$code} の商品について、在庫の数値を確認できませんでした。処理を行いません。", $actionCode . '_doing');
} else {
$logManager->logOutward("商品ID: {$code} の商品を、在庫: {$stock} に変更します。", $actionCode . '_doing');
$this->sendRequest($stock, $code);
}
}
break;
}
}
//error_log( date('[Y-m-d H:i:s] ') . 'Code: ' . $code . ' Stock: ' . $stock . "\n", 3, "/home/liquor-sato/temp/log.txt");
}
//$this->sendSalesRequest($orderData, $detailArray);
}
private function sendSalesRequest($orderData, $detailArray)
{
if (empty($detailArray)) {
return;
}
$headers = array(
'X-contract-id: ' . $this->contractId,
'X-access-token: ' . $this->token,
'Content-Type: application/x-www-form-urlencoded;charset=UTF-8'
);
$header = implode("\r\n", $headers);
$params = array(
'proc_info' => array(
'proc_division' => 'U'
),
'data' => array(
array(
'table_name' => 'TransactionHead',
'rows' => array(
array(
'transactionHeadDivision' => '1',
'cancelDivision' => '0',
'subtotal' => $orderData['subTotal'],
'subtotalDiscountPrice' => $orderData['discount'],
'total' => $orderData['totalPrice'],
'taxExclude' => $orderData['tax'],
'storeId' => '1',
'terminalId' => '99',
'terminalTranId' => $orderData['orderId'],
'terminalTranDateTime' => date('Y-m-d H:i:s'),
'sumDivision' => '2',
'sumDateTime' => date('Y-m-d'),
'carriage' => $orderData['deliveryFee'],
'commission' => $orderData['charge'],
)
)
), array(
'table_name' => 'TransactionDetail',
'rows' => array()
)
)
);
$details = array();
foreach($detailArray as $detail) {
$array = array(
'transactionDetailDivision' => '1',
'productId' => $detail['code'],
'productName' => $detail['name'],
'taxDivision' => '1',
'price' => $detail['price'],
'salesPrice' => $detail['price'],
'quantity' => $detail['quantity']
);
$details[] = $array;
}
$params['data'][1]['rows'] = $details;
$data = array(
'proc_name' => 'transaction_upd',
'params' => json_encode($params)
);
//error_log( date('[Y-m-d H:i:s] ') . 'Params: ' . print_r($params, true) . "\n", 3, "/home/liquor-sato/temp/log.txt");
$options = array(
'http' => array(
'method' => 'POST',
'content' => http_build_query($data),
'header' => $header
)
);
if (gethostname() !== 'zotac') {
$contents = file_get_contents($this->url, false, stream_context_create($options));
}
}
private function sendRequest($stock, $code, $procDetailDivision = 1)
{
if (empty($code)) {
return;
}
$headers = array(
'X-contract-id: ' . $this->contractId,
'X-access-token: ' . $this->token,
'Content-Type: application/x-www-form-urlencoded;charset=UTF-8'
);
$header = implode("\r\n", $headers);
$params = array(
'proc_info' => array(
'proc_division' => 'U',
'proc_detail_division' => $procDetailDivision
),
'data' => array(
array(
'table_name' => 'Stock',
'rows' => array(
array(
'storeId' => 1,
'productId' => $code,
'stockAmount' => $stock,
'stockDivision' => 15
)
)
)
)
);
$data = array(
'proc_name' => 'stock_upd',
'params' => json_encode($params)
);
$options = array(
'http' => array(
'method' => 'POST',
'content' => http_build_query($data),
'header' => $header
)
);
if (gethostname() !== 'zotac') {
$contents = file_get_contents($this->url, false, stream_context_create($options));
$logManager = LogManager::sharedInstance();
if ($procDetailDivision === 2) {
$logManager->logOutward("スマレジにデータを送信しました。商品ID: {$code} の商品を、在庫: {$stock} (相対値)に変更します。", 'sent_request', $contents);
} else {
$logManager->logOutward("スマレジにデータを送信しました。商品ID: {$code} の商品を、在庫: {$stock} (絶対値)に変更します。", 'sent_request', $contents);
}
$params = array(
'conditions' => array(
array('storeId' => '1'),
array('productId' => $code)
),
'table_name' => 'Stock'
);
$data = array(
'proc_name' => 'stock_ref',
'params' => json_encode($params)
);
$options = array(
'http' => array(
'method' => 'POST',
'content' => http_build_query($data),
'header' => $header
)
);
$contents = file_get_contents($this->url, false, stream_context_create($options));
$logManager->logOutward("スマレジのデータを確認します。商品ID: {$code} ", 'stock_confirm', $contents);
}
}
}