/** * カート内の商品の妥当性をチェックする. * * エラーが発生した場合は, 商品をカート内から削除又は数量を調整し, * エラーメッセージを返す. * * 1. 商品種別に関連づけられた配送業者の存在チェック * 2. 削除/非表示商品のチェック * 3. 販売制限数のチェック * 4. 在庫数チェック * * @param string $productTypeId 商品種別ID * @return string エラーが発生した場合はエラーメッセージ */ public function checkProducts($productTypeId) { /* @var $objProduct Product */ $objProduct = Application::alias('eccube.product'); /* @var $objDelivery DeliveryHelper */ $objDelivery = Application::alias('eccube.helper.delivery'); $arrDeliv = $objDelivery->getList($productTypeId); $tpl_message = ''; // カート内の情報を取得 $arrItems = $this->getCartList($productTypeId); foreach ($arrItems as &$arrItem) { $product =& $arrItem['productsClass']; /* * 表示/非表示商品のチェック */ if (Utils::isBlank($product) || $product['status'] != 1) { $this->delProduct($arrItem['cart_no'], $productTypeId); $tpl_message .= "※ 現時点で販売していない商品が含まれておりました。該当商品をカートから削除しました。\n"; } else { /* * 配送業者のチェック */ if (Utils::isBlank($arrDeliv)) { $tpl_message .= '※「' . $product['name'] . '」はまだ配送の準備ができておりません。'; $tpl_message .= '恐れ入りますがお問い合わせページよりお問い合わせください。' . "\n"; $this->delProduct($arrItem['cart_no'], $productTypeId); } /* * 販売制限数, 在庫数のチェック */ $limit = $objProduct->getBuyLimit($product); if (!is_null($limit) && $arrItem['quantity'] > $limit) { if ($limit > 0) { $this->setProductValue($arrItem['id'], 'quantity', $limit, $productTypeId); $total_inctax = $limit * TaxRuleHelper::sfCalcIncTax($arrItem['price'], $product['product_id'], $arrItem['id'][0]); $this->setProductValue($arrItem['id'], 'total_inctax', $total_inctax, $productTypeId); $tpl_message .= '※「' . $product['name'] . '」は販売制限(または在庫が不足)しております。'; $tpl_message .= "一度に数量{$limit}を超える購入はできません。\n"; } else { $this->delProduct($arrItem['cart_no'], $productTypeId); $tpl_message .= '※「' . $product['name'] . "」は売り切れました。\n"; continue; } } } } return $tpl_message; }
/** * DBに商品データを登録する * * @param UploadFile $objUpFile UploadFileインスタンス * @param UploadFile $objDownFile UploadFileインスタンス * @param array $arrList フォーム入力パラメーター配列 * @return integer 登録商品ID */ public function lfRegistProduct(&$objUpFile, &$objDownFile, $arrList) { $objQuery = Application::alias('eccube.query'); /* @var $objDb DbHelper */ $objDb = Application::alias('eccube.helper.db'); // 配列の添字を定義 $checkArray = array('name', 'status', 'main_list_comment', 'main_comment', 'deliv_fee', 'comment1', 'comment2', 'comment3', 'comment4', 'comment5', 'comment6', 'sale_limit', 'deliv_date_id', 'maker_id', 'note'); $arrList = Utils::arrayDefineIndexes($arrList, $checkArray); // INSERTする値を作成する。 $sqlval['name'] = $arrList['name']; $sqlval['status'] = $arrList['status']; $sqlval['main_list_comment'] = $arrList['main_list_comment']; $sqlval['main_comment'] = $arrList['main_comment']; $sqlval['comment1'] = $arrList['comment1']; $sqlval['comment2'] = $arrList['comment2']; $sqlval['comment3'] = $arrList['comment3']; $sqlval['comment4'] = $arrList['comment4']; $sqlval['comment5'] = $arrList['comment5']; $sqlval['comment6'] = $arrList['comment6']; $sqlval['deliv_date_id'] = $arrList['deliv_date_id']; $sqlval['maker_id'] = $arrList['maker_id']; $sqlval['note'] = $arrList['note']; $sqlval['update_date'] = 'CURRENT_TIMESTAMP'; $sqlval['creator_id'] = $_SESSION['member_id']; $arrRet = $objUpFile->getDBFileList(); $sqlval = array_merge($sqlval, $arrRet); for ($cnt = 1; $cnt <= PRODUCTSUB_MAX; $cnt++) { $sqlval['sub_title' . $cnt] = $arrList['sub_title' . $cnt]; $sqlval['sub_comment' . $cnt] = $arrList['sub_comment' . $cnt]; } $objQuery->begin(); // 新規登録(複製時を含む) if ($arrList['product_id'] == '') { $product_id = $objQuery->nextVal('dtb_products_product_id'); $sqlval['product_id'] = $product_id; // INSERTの実行 $sqlval['create_date'] = 'CURRENT_TIMESTAMP'; $objQuery->insert('dtb_products', $sqlval); $arrList['product_id'] = $product_id; // カテゴリを更新 $objDb->updateProductCategories($arrList['category_id'], $product_id); // 複製商品の場合には規格も複製する if ($arrList['copy_product_id'] != '' && Utils::sfIsInt($arrList['copy_product_id'])) { if (!$arrList['has_product_class']) { //規格なしの場合、複製は価格等の入力が発生しているため、その内容で追加登録を行う $this->lfCopyProductClass($arrList, $objQuery); } else { //規格がある場合の複製は複製元の内容で追加登録を行う // dtb_products_class のカラムを取得 /* @var $dbFactory DBFactory */ $dbFactory = Application::alias('eccube.db.factory'); $arrColList = $objQuery->listTableFields('dtb_products_class'); $arrColList_tmp = array_flip($arrColList); // 複製しない列 unset($arrColList[$arrColList_tmp['product_class_id']]); //規格ID unset($arrColList[$arrColList_tmp['product_id']]); //商品ID unset($arrColList[$arrColList_tmp['create_date']]); // 複製元商品の規格データ取得 $col = Utils::sfGetCommaList($arrColList); $table = 'dtb_products_class'; $where = 'product_id = ?'; $objQuery->setOrder('product_class_id'); $arrProductsClass = $objQuery->select($col, $table, $where, array($arrList['copy_product_id'])); // 規格データ登録 $objQuery = Application::alias('eccube.query'); foreach ($arrProductsClass as $arrData) { $sqlval = $arrData; $sqlval['product_class_id'] = $objQuery->nextVal('dtb_products_class_product_class_id'); $sqlval['deliv_fee'] = $arrList['deliv_fee']; $sqlval['point_rate'] = $arrList['point_rate']; $sqlval['sale_limit'] = $arrList['sale_limit']; $sqlval['product_id'] = $product_id; $sqlval['create_date'] = 'CURRENT_TIMESTAMP'; $sqlval['update_date'] = 'CURRENT_TIMESTAMP'; $objQuery->insert($table, $sqlval); } } } // 更新 } else { $product_id = $arrList['product_id']; // 削除要求のあった既存ファイルの削除 $arrRet = $this->lfGetProductData_FromDB($arrList['product_id']); // TODO: UploadFile::deleteDBFileの画像削除条件見直し要 $objImage = new Image($objUpFile->temp_dir); $arrKeyName = $objUpFile->keyname; $arrSaveFile = $objUpFile->save_file; $arrImageKey = array(); foreach ($arrKeyName as $key => $keyname) { if ($arrRet[$keyname] && !$arrSaveFile[$key]) { $arrImageKey[] = $keyname; $has_same_image = $this->lfHasSameProductImage($arrList['product_id'], $arrImageKey, $arrRet[$keyname]); if (!$has_same_image) { $objImage->deleteImage($arrRet[$keyname], $objUpFile->save_dir); } } } $objDownFile->deleteDBDownFile($arrRet); // UPDATEの実行 $where = 'product_id = ?'; $objQuery->update('dtb_products', $sqlval, $where, array($product_id)); // カテゴリを更新 $objDb->updateProductCategories($arrList['category_id'], $product_id); } // 商品登録の時は規格を生成する。複製の場合は規格も複製されるのでこの処理は不要。 if ($arrList['copy_product_id'] == '') { // 規格登録 if ($objDb->hasProductClass($product_id)) { // 規格あり商品(商品規格テーブルのうち、商品登録フォームで設定するパラメーターのみ更新) $this->lfUpdateProductClass($arrList); } else { // 規格なし商品(商品規格テーブルの更新) $arrList['product_class_id'] = $this->lfInsertDummyProductClass($arrList); } } // 商品ステータス設定 /* @var $objProduct Product */ $objProduct = Application::alias('eccube.product'); $objProduct->setProductStatus($product_id, $arrList['product_status']); // 税情報設定 if (OPTION_PRODUCT_TAX_RULE && !$objDb->hasProductClass($product_id)) { TaxRuleHelper::setTaxRuleForProduct($arrList['tax_rate'], $arrList['product_id'], $arrList['product_class_id']); } // 関連商品登録 $this->lfInsertRecommendProducts($objQuery, $arrList, $product_id); $objQuery->commit(); return $product_id; }
/** * Page のAction. * * @return void */ public function action() { //決済処理中ステータスのロールバック /* @var $objPurchase PurchaseHelper */ $objPurchase = Application::alias('eccube.helper.purchase'); $objPurchase->cancelPendingOrder(PENDING_ORDER_CANCEL_FLAG); /* @var $objCustomer Customer */ $objCustomer = Application::alias('eccube.customer'); /* @var $objProduct Product */ $objProduct = Application::alias('eccube.product'); if (!Utils::sfIsInt($_GET['order_id'])) { Utils::sfDispSiteError(CUSTOMER_ERROR); } $order_id = $_GET['order_id']; $this->is_price_change = false; //受注データの取得 $this->tpl_arrOrderData = $objPurchase->getOrder($order_id, $objCustomer->getValue('customer_id')); if (empty($this->tpl_arrOrderData)) { Utils::sfDispSiteError(CUSTOMER_ERROR); } $this->arrShipping = $this->lfGetShippingDate($objPurchase, $order_id, $this->arrWDAY); $this->isMultiple = count($this->arrShipping) > 1; // 支払い方法の取得 $this->arrPayment = Application::alias('eccube.helper.payment')->getIDValueList(); // 受注商品明細の取得 $this->tpl_arrOrderDetail = $objPurchase->getOrderDetail($order_id); foreach ($this->tpl_arrOrderDetail as $product_index => $arrOrderProductDetail) { //必要なのは商品の販売金額のみなので、遅い場合は、別途SQL作成した方が良い $arrTempProductDetail = $objProduct->getProductsClass($arrOrderProductDetail['product_class_id']); // 税計算 $this->tpl_arrOrderDetail[$product_index]['price_inctax'] = $this->tpl_arrOrderDetail[$product_index]['price'] + TaxRuleHelper::calcTax($this->tpl_arrOrderDetail[$product_index]['price'], $this->tpl_arrOrderDetail[$product_index]['tax_rate'], $this->tpl_arrOrderDetail[$product_index]['tax_rule']); $arrTempProductDetail['price02_inctax'] = TaxRuleHelper::sfCalcIncTax($arrTempProductDetail['price02'], $arrTempProductDetail['product_id'], $arrTempProductDetail['product_class_id']); if ($this->tpl_arrOrderDetail[$product_index]['price_inctax'] != $arrTempProductDetail['price02_inctax']) { $this->is_price_change = true; } $this->tpl_arrOrderDetail[$product_index]['product_price_inctax'] = $arrTempProductDetail['price02_inctax'] ? $arrTempProductDetail['price02_inctax'] : 0; } $this->tpl_arrOrderDetail = $this->setMainListImage($this->tpl_arrOrderDetail); $objPurchase->setDownloadableFlgTo($this->tpl_arrOrderDetail); // モバイルダウンロード対応処理 $this->lfSetAU($this->tpl_arrOrderDetail); // 受注メール送信履歴の取得 $this->tpl_arrMailHistory = $this->lfGetMailHistory($order_id); }
/** * 受注商品一覧側に商品を追加 * * @param FormParam $objFormParam FormParam インスタンス * @param array $arrProductClassIds 対象配列の商品規格ID * @param int $insert_product_class_id 追加商品規格ID * @param array $arrAddProductInfo 追加データ * @return array|null $arrAddProducts 更新データ */ public function checkInsertOrderProducts(&$objFormParam, $arrProductClassIds, $insert_product_class_id, $arrAddProductInfo) { if (!$arrProductClassIds || !in_array($insert_product_class_id, $arrProductClassIds)) { $arrAddProducts = array(); $arrTax = TaxRuleHelper::getTaxRule(0, $insert_product_class_id); $arrAddProductInfo['product_name'] = $arrAddProductInfo['product_name'] ? $arrAddProductInfo['product_name'] : $arrAddProductInfo['name']; $arrAddProductInfo['price'] = $arrAddProductInfo['price'] ? $arrAddProductInfo['price'] : $arrAddProductInfo['price02']; $arrAddProductInfo['quantity'] = 1; $arrAddProductInfo['tax_rate'] = $objFormParam->getValue('order_tax_rate') == '' ? $arrTax['tax_rate'] : $objFormParam->getValue('order_tax_rate'); $arrAddProductInfo['tax_rule'] = $objFormParam->getValue('order_tax_rule') == '' ? $arrTax['tax_rule'] : $objFormParam->getValue('order_tax_rule'); foreach ($this->arrProductKeys as $insert_key) { $value = $objFormParam->getValue($insert_key); $arrAddProducts[$insert_key] = is_array($value) ? $value : array(); $arrAddProducts[$insert_key][] = $arrAddProductInfo[$insert_key]; } return $arrAddProducts; } else { //受注商品の数量は、複数配送側の集計で出しているので、重複しても数量を増やさない。 return null; } }
/** * 配送商品を設定する. * * @param integer $shipping_id 配送先ID * @param integer $product_class_id 商品規格ID * @param integer $quantity 数量 * @return void */ public function setShipmentItemTemp($shipping_id, $product_class_id, $quantity) { // 配列が長くなるので, リファレンスを使用する $arrItems =& $_SESSION['shipping'][$shipping_id]['shipment_item'][$product_class_id]; $arrItems['shipping_id'] = $shipping_id; $arrItems['product_class_id'] = $product_class_id; $arrItems['quantity'] = $quantity; /* @var $objProduct Product */ $objProduct = Application::alias('eccube.product'); // カート情報から読みこめば済むと思うが、一旦保留。むしろ、カート情報も含め、セッション情報を縮小すべきかもしれない。 /* $objCartSession = Application::alias('eccube.cart_session'); $cartKey = $objCartSession->getKey(); // 詳細情報を取得 $cartItems = $objCartSession->getCartList($cartKey); */ if (empty($arrItems['productsClass'])) { $product =& $objProduct->getDetailAndProductsClass($product_class_id); $arrItems['productsClass'] = $product; } $arrItems['price'] = $arrItems['productsClass']['price02']; $inctax = TaxRuleHelper::sfCalcIncTax($arrItems['price'], $arrItems['productsClass']['product_id'], $arrItems['productsClass']['product_class_id']); $arrItems['total_inctax'] = $inctax * $arrItems['quantity']; }
/** * 商品情報の配列に税込金額を設定する * * @param array $arrProduct 商品情報の配列 * @return void */ public function setIncTaxToProduct(&$arrProduct) { $arrProduct['price01_min_inctax'] = isset($arrProduct['price01_min']) ? TaxRuleHelper::sfCalcIncTax($arrProduct['price01_min'], $arrProduct['product_id']) : null; $arrProduct['price01_max_inctax'] = isset($arrProduct['price01_max']) ? TaxRuleHelper::sfCalcIncTax($arrProduct['price01_max'], $arrProduct['product_id']) : null; $arrProduct['price02_min_inctax'] = isset($arrProduct['price02_min']) ? TaxRuleHelper::sfCalcIncTax($arrProduct['price02_min'], $arrProduct['product_id']) : null; $arrProduct['price02_max_inctax'] = isset($arrProduct['price02_max']) ? TaxRuleHelper::sfCalcIncTax($arrProduct['price02_max'], $arrProduct['product_id']) : null; }
/** * 入力エラーチェック. * * @param FormParam $objFormParam * @return array $objErr->arrErr エラー内容 */ public function lfCheckError(&$objFormParam, TaxRuleHelper &$objTaxRule) { $arrErr = $objFormParam->checkError(); $arrForm = $objFormParam->getHashArray(); /* @var $objErr CheckError */ $objErr = Application::alias('eccube.check_error', $arrForm); // tax_rule_id の正当性チェック if (!empty($arrForm['tax_rule_id'])) { if (!Utils::sfIsInt($arrForm['tax_rule_id']) || !$objTaxRule->getTaxRuleData($arrForm['tax_rule_id'])) { // tax_rule_idが指定されていて、且つその値が不正と思われる場合はエラー $arrErr['tax_rule_id'] = '※ 税規約IDが不正です<br />'; } } // 適用日時チェック $objErr->doFunc(array('適用日時', 'apply_date_year', 'apply_date_month', 'apply_date_day'), array('CHECK_DATE')); if (Utils::isBlank($objErr->arrErr['apply_date_year']) && $arrForm['tax_rule_id'] != '0') { $apply_date = Utils::sfGetTimestampistime($arrForm['apply_date_year'], sprintf("%02d", $arrForm['apply_date_month']), sprintf("%02d", $arrForm['apply_date_day']), sprintf("%02d", $arrForm['apply_date_hour']), sprintf("%02d", $arrForm['apply_date_minutes'])); // 税規約情報読み込み $arrTaxRuleByTime = $objTaxRule->getTaxRuleByTime($apply_date); // 編集中のレコード以外に同じ消費税率、課税規則が存在する場合 if (!Utils::isBlank($arrTaxRuleByTime) && $arrTaxRuleByTime['tax_rule_id'] != $arrForm['tax_rule_id'] && $arrTaxRuleByTime['apply_date'] == $apply_date) { $arrErr['apply_date'] = '※ 既に同じ適用日時で登録が存在します。<br />'; } } if (!Utils::isBlank($objErr->arrErr)) { $arrErr = array_merge($arrErr, $objErr->arrErr); } return $arrErr; }
/** * ポイント付与 * $product_id が使われていない。 * @param int $price * @param float $point_rate * @param int $rule * @return double */ public static function sfPrePoint($price, $point_rate, $rule = POINT_RULE) { $real_point = $point_rate / 100; $ret = $price * $real_point; $ret = TaxRuleHelper::roundByCalcRule($ret, $rule); return $ret; }
/** * 規格編集画面を表示する * * @param FormParam $objFormParam */ public function doPreEdit(&$objFormParam) { $product_id = $objFormParam->getValue('product_id'); /* @var $objProduct Product */ $objProduct = Application::alias('eccube.product'); $existsProductsClass = $objProduct->getProductsClassFullByProductId($product_id); // 規格のデフォルト値(全ての組み合わせ)を取得し, フォームに反映 $class_id1 = $existsProductsClass[0]['class_id1']; $class_id2 = $existsProductsClass[0]['class_id2']; $objFormParam->setValue('class_id1', $class_id1); $objFormParam->setValue('class_id2', $class_id2); $this->doDisp($objFormParam); /* * 登録済みのデータで, フォームの値を上書きする. * * 登録済みデータと, フォームの値は, 配列の形式が違うため, * 同じ形式の配列を生成し, マージしてフォームの値を上書きする */ $arrKeys = array('classcategory_id1', 'classcategory_id2', 'product_code', 'classcategory_name1', 'classcategory_name2', 'stock', 'stock_unlimited', 'price01', 'price02', 'product_type_id', 'down_filename', 'down_realfilename', 'upload_index', 'tax_rate'); $arrFormValues = $objFormParam->getSwapArray($arrKeys); // フォームの規格1, 規格2をキーにした配列を生成 $arrClassCatKey = array(); foreach ($arrFormValues as $formValue) { $arrClassCatKey[$formValue['classcategory_id1']][$formValue['classcategory_id2']] = $formValue; } // 登録済みデータをマージ foreach ($existsProductsClass as $existsValue) { $arrClassCatKey[$existsValue['classcategory_id1']][$existsValue['classcategory_id2']] = $existsValue; } // 規格のデフォルト値に del_flg をつけてマージ後の1次元配列を生成 $arrMergeProductsClass = array(); foreach ($arrClassCatKey as $arrC1) { foreach ($arrC1 as $arrValues) { $arrValues['del_flg'] = (string) $arrValues['del_flg']; if (Utils::isBlank($arrValues['del_flg']) || $arrValues['del_flg'] === '1') { $arrValues['del_flg'] = '1'; } else { $arrValues['del_flg'] = '0'; } // 消費税率を設定 if (OPTION_PRODUCT_TAX_RULE) { $arrRet = TaxRuleHelper::getTaxRule($arrValues['product_id'], $arrValues['product_class_id']); $arrValues['tax_rate'] = $arrRet['tax_rate']; } $arrMergeProductsClass[] = $arrValues; } } // 登録済みのデータで上書き $objFormParam->setParam(Utils::sfSwapArray($arrMergeProductsClass)); // $arrMergeProductsClass で product_id が配列になってしまうため数値で上書き $objFormParam->setValue('product_id', $product_id); // check を設定 $arrChecks = array(); $index = 0; foreach ($objFormParam->getValue('del_flg') as $key => $val) { if ($val === '0') { $arrChecks[$index] = 1; } $index++; } $objFormParam->setValue('check', $arrChecks); // class_id1, class_id2 を取得値で上書き $objFormParam->setValue('class_id1', $class_id1); $objFormParam->setValue('class_id2', $class_id2); }