バージョン選択

フォーラム

メニュー

オンライン状況

54 人のユーザが現在オンラインです。 (45 人のユーザが フォーラム を参照しています。)
登録ユーザ: 0
ゲスト: 54
もっと...

サイト内検索

質問 > 管理機能 > 商品複製時(規格あり)ついて

管理機能

新規スレッドを追加する

スレッド表示 | 新しいものから 前のトピック | 次のトピック | 下へ
投稿者 スレッド
motorp
投稿日時: 2014/9/18 21:16
対応状況: −−−
常連
登録日: 2013/12/26
居住地:
投稿: 45
商品複製時(規格あり)ついて
規格あり商品を複製した時なのですが

複製した商品の 規格基本データ(classcategory_id1=0 classcategory_id1=0)のデータ上に
複製元のデータが残ってしまい
毎回 dtb_products_class データベース上で直接打ち替えています


これを改善したく
product_code price01 price02 
(商品コード)(通常価格)(販売価格)

の3点だけでも そのまま複製される仕様になっているのを
変更したいと考えていました。


LC_Page_Admin_Products_Produc.php を見たところ…
自身の知識では難しいと思い ご相談させてください。


1.商品複製したときに 規格自体を複製させない
2.そのまま複製させてしまい 商品規格登録画面で(classcategory_id1=0 classcategory_id1=0)のデータを表示させて上書き


上記のどちらかを行いたいのですが

1.の場合は簡単かと思ったのですが 
LC_Page_Admin_Products_Product.php内で
// 規格情報ありなしフラグ取得
// 商品登録の時は規格を生成する。
* 規格を設定していない商品を商品規格テーブルに登録
* 規格データをコピーする

といろいろあって さわるのを躊躇しました。




2.の場合 テンプレート内でid=0を表示させてないのでは? と思ったのですが、違ったようで諦め
LC_Page_Admin_Products_ProductClass 内を確認した処 ↓以下の部分で非表示させてるのでしょうか?

$objQuery->delete('dtb_products_class', 'product_id = ? AND (classcategory_id1 <> 0 OR classcategory_id2 <> 0)', array($product_id));


いろいろ調べたりフォーラム内で教えて頂いたりで手を加えているのですが
1、2 ともに
私の拙い知識では手が出せなく 出来るものか教えて頂けると助かります。

※ classcategory_id1 <> 0 の
 <> の比較が初見で…そのようなレベルです。お手数おかけします。



-------------------------------------------------------------------------
[EC-CUBE]
2.12.3 
[PHP]
PHP 5.3.17
[データベース]
MySQL 5.1.47
[WEBサーバ]
Apache
ec9iii
投稿日時: 2014/9/18 22:38
対応状況: −−−
一人前
登録日: 2014/9/8
居住地:
投稿: 117
Re: 商品複製時(規格あり)ついて
規格あり商品をコピーして、規格なし商品を作成するということでよろしいでしょうか?
いろいろ手法はあると思いますが、ポイントになりそうな箇所を記載します。

/data/class/pages/admin/products/LC_Page_Admin_Products_Product.php


    /**
     * DBから商品データを取得する
     *
     * @param  integer $product_id 商品ID
     * @return array   商品データ配列
     */
    public function lfGetProductData_FromDB($product_id)
    {
        $objQuery =& SC_Query_Ex::getSingletonInstance();
        $arrProduct = array();

        // 商品データ取得
        $col = '*';
        $table = <<< __EOF__
            dtb_products AS T1
            LEFT JOIN (
                SELECT product_id AS product_id_sub,
                    product_code,
                    price01,
                    price02,
                    deliv_fee,
                    stock,
                    stock_unlimited,
                    sale_limit,
                    point_rate,
                    product_type_id,
                    down_filename,
                    down_realfilename
                FROM dtb_products_class
            ) AS T2
                ON T1.product_id = T2.product_id_sub
__EOF__;
        $where = 'product_id = ?';
        $objQuery->setLimit('1');
        $arrProduct = $objQuery->select($col, $table, $where, array($product_id));

        // カテゴリID取得
        $col = 'category_id';
        $table = 'dtb_product_categories';
        $where = 'product_id = ?';
        $objQuery->setOption('');
        $arrProduct[0]['category_id'] = $objQuery->getCol($col, $table, $where, array($product_id));

        // 規格情報ありなしフラグ取得
        $objDb = new SC_Helper_DB_Ex();
        $arrProduct[0]['has_product_class'] = $objDb->sfHasProductClass($product_id);
        
        $arrProduct[0]['has_product_class'] = false;    //←この行を追加

        // 規格が登録されていなければ規格ID取得
        if ($arrProduct[0]['has_product_class'] == false) {
            $arrProduct[0]['product_class_id'] = SC_Utils_Ex::sfGetProductClassId($product_id,'0','0');
        }

        // 商品ステータス取得
        $objProduct = new SC_Product_Ex();
        $productStatus = $objProduct->getProductStatus(array($product_id));
        $arrProduct[0]['product_status'] = $productStatus[$product_id];

        // 関連商品データ取得
        $arrRecommend = $this->lfGetRecommendProductsData_FromDB($product_id);
        $arrProduct[0] = array_merge($arrProduct[0], $arrRecommend);

        return $arrProduct[0];
    }




    /**
     * 規格データをコピーする
     *
     * @param  array   $arrList  フォーム入力パラメーター配列
     * @param  object  $objQuery SC_Queryインスタンス
     * @return boolean エラーフラグ
     */
    public function lfCopyProductClass($arrList, &$objQuery)
    {
        // 複製元のdtb_products_classを取得(規格なしのため、1件のみの取得)
        $col = '*';
        $table = 'dtb_products_class';
        $where = 'product_id = ?';
        $where .= ' AND classcategory_id1 = 0';     //←この行を追加
        $where .= ' AND classcategory_id2 = 0';     //←この行を追加
        $arrProductClass = $objQuery->select($col, $table, $where, array($arrList['copy_product_id']));

        //トランザクション開始
        $objQuery->begin();
        $err_flag = false;
        //非編集項目は複製、編集項目は上書きして登録
        foreach ($arrProductClass as $records) {
            foreach ($records as $key => $value) {
                if (isset($arrList[$key])) {
                    switch ($key) {
                    case 'stock_unlimited':
                        $records[$key] = (int) $arrList[$key];
                        break;
                    default:
                        $records[$key] = $arrList[$key];
                        break;
                    }
                }
            }

            $records['del_flg'] = 0;     //←この行を追加
            $records['product_class_id'] = $objQuery->nextVal('dtb_products_class_product_class_id');
            $records['update_date'] = 'CURRENT_TIMESTAMP';
            $records['create_date'] = 'CURRENT_TIMESTAMP';
            $objQuery->insert($table, $records);
            //エラー発生時は中断
            if ($objQuery->isError()) {
                $err_flag = true;
                continue;
            }
        }
        //トランザクション終了
        if ($err_flag) {
            $objQuery->rollback();
        } else {
            $objQuery->commit();
        }

        return !$err_flag;
    }


このままでは編集時などにも影響してしまいますので、
上記の追加した行の部分がコピー時のみ通るようになれば良さそうに思います。
なお、classcategory_id1 = 0 AND classcategory_id2 = 0 のデータが存在する前提です。
(※Ver.2.13.2で試していますが、お使いのバージョンでも同じだと思います)

ご参考になりましたら幸いです。
seiyawada
投稿日時: 2014/9/18 22:40
対応状況: −−−
常連
登録日: 2014/4/28
居住地:
投稿: 42
Re: 商品複製時(規格あり)ついて
1の場合:

LC_Page_Admin_Products_Product.phpにて、lfRegistProduct関数の
// 複製商品の場合には規格も複製する
部分をコメントアウトしてみてください。
motorp
投稿日時: 2014/9/19 17:18
対応状況: −−−
常連
登録日: 2013/12/26
居住地:
投稿: 45
Re: 商品複製時(規格あり)ついて
ありがとうございます。

コメントアウトのみですと
商品は複製され dtb_products上では商品データがあるのですが 
管理画面で出力されない状態でした。
product_classに同ID付きのデータが生成されてないからでしょうか


ec9iii様のご教授のまま試した処
規格は無くなり 通常に登録が出来ました。

新規登録、通常編集 の状態も特に問題が無いようなのですが、
どのようなことが懸念されますでしょうか?

もしおわかりでしたら簡単にでも構いませんので教えて頂けますと助かります。
motorp
投稿日時: 2014/9/19 19:44
対応状況: −−−
常連
登録日: 2013/12/26
居住地:
投稿: 45
Re: 商品複製時(規格あり)ついて
複製した商品を
更に編集するときに弊害(更新がされない)があるということがわかりました。

ありがとうございました。

この場合で手を加えてみたいと思います。
ec9iii
投稿日時: 2014/9/19 23:11
対応状況: −−−
一人前
登録日: 2014/9/8
居住地:
投稿: 117
Re: 商品複製時(規格あり)ついて
すみません。ちょっと自己修正させてください。
seiyawada様の案を元にブラッシュアップしてみました。
たぶんコーディング的にはこちらのほうが理にかなっています。


lfCopyProductClassの部分の私の投稿は忘れて頂き、
lfRegistProduct内で、


// 複製商品の場合には規格も複製する
$arrList['copy_product_id'] = '';       //←この行を追加
if ($arrList['copy_product_id'] != '' && SC_Utils_Ex::sfIsInt($arrList['copy_product_id'])) {


こうすることで、後続処理のlfInsertDummyProductClassにて、
規格なし商品のダミー規格が登録されますので、これがベストだと思います。


いちおう、理解を深めて頂くために補足です。

1.読込時は、'has_product_class'をFalseにして、擬似的に規格無しと認識させる。
2.登録時の途中で、'copy_product_id'を空白にして、複製した商品ではないと擬似的に認識させる。

という感じです。
なお、商品コードや価格情報はdtb_products_classに持っていますので、
classcategory_id1 = 0 AND classcategory_id2 = 0 AND del_flg = 0 のデータが規格無し商品のダミー規格です。
motorp
投稿日時: 2014/9/20 21:23
対応状況: −−−
常連
登録日: 2013/12/26
居住地:
投稿: 45
Re: 商品複製時(規格あり)ついて
修正までご連絡いただきありがとうございます。

試させて頂きました処

classcategory_id1 = 0 classcategory_id2 = 0 が複製元のデータに新しいproduct_idが上書きされてしまうようです。

複製元の classcategory_id1 = 0 classcategory_id2 = 0 がなくなります。


全く別のパターンで思いついたのですが
// 複製商品の場合には規格も複製する 

// 複製しない列
unset($arrColList[$arrColList_tmp['product_class_id']]);     //規格ID
unset($arrColList[$arrColList_tmp['product_id']]);           //商品ID
unset($arrColList[$arrColList_tmp['create_date']]);
unset($arrColList[$arrColList_tmp['price01']]);
unset($arrColList[$arrColList_tmp['price02']]);


price01、price02を追加してみたのですが

ここで このまま複製すると
価格 がNullになり エラーとなりました。当然ですが

ここで
全て(商品登録画面のprice01.price02)に書き換えるという
ことができないでしょうか




motorp
投稿日時: 2014/9/21 1:33
対応状況: −−−
常連
登録日: 2013/12/26
居住地:
投稿: 45
Re: 商品複製時(規格あり)ついて
自己レスです。

根本的に全く違う方法で解決いたしました。
複製時と編集時にファイル自体を別にするというすごく直球なことを思いつきました。

規格ごとにポイント設定している場合、編集時に全部同じポイントになってしまうのを
回避するのにも有効でしょうか。

data/class/pages/admin/products/
LC_Page_Admin_Products_Product.phpをコピー
LC_Page_Admin_Products_Product2.php にファイル名変更

data/class_extends/pages/admin/products/
LC_Page_Admin_Products_Product_Ex.phpをコピー
LC_Page_Admin_Products_Product2_Ex.php にファイル名変更

admin/products/product.phpをコピー
admin/products/product2.php にファイル名変更


各ファイルの冒頭
require_once CLASS_EX_REALDIR . 'page_extends/〜
class LC_Page_Admin_Products〜

の2行を それぞれのファイル名(Product2)に変更



新しく作ったファイル LC_Page_Admin_Products_Product2.phpの

(1) function lfInitFormParam 内
if (!$arrPost['has_product_class']) から以下2行を if内から移動して通常に登録させる

$objFormParam->addParam(NORMAL_PRICE_TITLE, 'price01', PRICE_LEN, 'n', array('NUM_CHECK', 'MAX_LENGTH_CHECK'));
$objFormParam->addParam(SALE_PRICE_TITLE, 'price02', PRICE_LEN, 'n', array('EXIST_CHECK', 'NUM_CHECK', 'MAX_LENGTH_CHECK'));

※ポイントを規格ごとにしてる場合は LC_Page_Admin_Products_Product.phpの
if (!$arrPost['has_product_class']) 内にpoint_rateを入れる



(2) // 複製商品の場合には規格も複製する
// 規格データ登録に追加

$sqlval['price01'] = $arrList['price01'];
$sqlval['price02'] = $arrList['price02'];


(3) function lfUpdateProductClass 内に追加

$sqlval['price01'] = $arrList['price01'];
$sqlval['price02'] = $arrList['price02'];




data/Smarty/templates/admin/products/index.tpl
<td class="menu" rowspan="2"><span class="icon_copy"><a href="<!--{$smarty.const.ROOT_URLPATH}-->" onclick="fnChangeAction('./product.php'); fnModeSubmit('copy', 'product_id', <!--{$arrProducts[cnt].product_id}-->); return false;" >複製</a></span></td>
変更

<td class="menu" rowspan="2"><span class="icon_copy"><a href="<!--{$smarty.const.ROOT_URLPATH}-->" onclick="fnChangeAction('./product.php'); fnModeSubmit('copy', 'product_id', <!--{$arrProducts[cnt].product_id}-->); return false;" >複製</a></span></td>



以下 2ファイルの <!--{if $arrForm.has_product_class != true}--> クラスがある場合に非表示になるのを消す
data/Smarty/templates/admin/products/product.tpl
data/Smarty/templates/admin/products/product.tpl


これで 複製の時は規格を複製しながら 新しく通常価格・販売価格を設定(但し規格側は全て同じ価格になります)
編集の時は今まで通り 規格で分けている 通常価格・販売価格 は上書きがされないようになりました。

思いついてやってみたことですので
もしなにか 間違っていること、ご指摘などありましたら ご教授ください。
ec9iii
投稿日時: 2014/9/21 2:29
対応状況: −−−
一人前
登録日: 2014/9/8
居住地:
投稿: 117
Re: 商品複製時(規格あり)ついて
すみません。修正版の仕様、間違ってましたね。
私のデータベースも、よく見ると上書きされてしまっていました。(汗)


修正内容を拝見させて頂きましたが、ぱっと見る限り大丈夫だと思います。(すみません、試せてはいません。)
ファイルを分けておられるので、
念のため戻るボタンや画像アップロードなど、画面遷移が行われるところで正しく遷移できるかのテストを行って頂くと良さそうに思います。


また、ファイルを分けてしまうデメリットとして、
他の箇所に修正やカスタマイズを行った場合に2ファイルともに修正が必要になりますので、
ここまでできておられるのでしたら、
できれば「複製時かどうか」のif文で切り分けてしまうのも良いのでは、と思いました。

逆にファイルを分けるメリットとして、
「既存の編集などには影響しない」ということでもありますので、このあたりは好みになりそうですね。



-------

後で見る方のために整理させて頂きたいのですが、

私やseiyawada様の案では、
1.商品複製したときに 規格自体を複製させない

でしたが、最終的には
2.そのまま複製させてしまい 商品規格登録画面で(classcategory_id1=0 classcategory_id1=0)のデータを表示させて上書き
(正しくは規格登録画面に遷移する前に上書きされている)

ということですよね?

また、「規格ごとにポイント設定している場合〜」は、
独自のカスタマイズを行なわれているということだと思います。


以下 2ファイルの <!--{if $arrForm.has_product_class != true}--> クラスがある場合に非表示になるのを消す
に関しては、おそらく以下の記載ミスだと思いますので、正しておきますね。
data/Smarty/templates/admin/products/product.tpl
data/Smarty/templates/admin/products/confirm.tpl


もし間違っておりましたらご指摘頂けますと幸いです。
motorp
投稿日時: 2014/9/22 16:18
対応状況: 解決済
常連
登録日: 2013/12/26
居住地:
投稿: 45
Re: 商品複製時(規格あり)ついて
2.そのまま複製させてしまい 商品規格登録画面で(classcategory_id1=0 classcategory_id1=0)のデータを表示させて上書き
(正しくは規格登録画面に遷移する前に上書きされている)

その通りです。

ファイル名の訂正補足も重ねてお礼申し上げます。
ありがとうございました。

結果最終的には 複製時に商品コードも
上書きできるようにしまして、
意図していた通りになりました。

色々とご相談にのって頂きまして感謝致します。

スレッド表示 | 新しいものから 前のトピック | 次のトピック | トップ


 



ログイン


EC-CUBE公式 Amazon Payプラグイン

統計情報

総メンバー数は88,724名です
総投稿数は109,953件です

投稿数ランキング

1
seasoft
7367
2
468
3217
3
AMUAMU
2712
4
nanasess
2313
5
umebius
2085
6
yuh
1819
7
h_tanaka
1638
8
red
1570
9
mcontact
1286
10
tsuji
958
11
fukap
907
12
shutta
835
13
tao_s
799
14 ramrun 789
15 karin 689
16 sumida 641
17
homan
633
18 DELIGHT 572
19
patapata
502
20
flealog
485


ネットショップの壺

EC-CUBEインテグレートパートナー

Copyright© EC-CUBE CO.,LTD. All Rights Reserved.