mcpField
B
bitrix-catalog

bitrix-catalog

github.com/bxmaximum開発47292 回インストール2 週間前に更新
リポジトリ

bitrix-catalog について

Bitrix のトレードカタログ開発向けスキルです。商品、価格、SKU オファー、在庫を扱い、再計算や店舗アクセスに配慮した ORM 読み取りとモデル経由の書き込み方法を説明します。

主な機能

  1. 01商品と価格の ORM 読み取り
  2. 02モデル経由の商品・価格の書き込み
  3. 03カタログ情報ブロックと SKU の設定
  4. 04店舗在庫とアクセスフィルター
  5. 05価格タイプと VAT の指針

活用シーン

  1. 01商品の数量や VAT の更新
  2. 02カタログ検証を通した価格の追加
  3. 03店舗アクセス制限下での在庫参照
  4. 04SKU オファーを持つ商品の処理

インストール

コマンドをコピーしてターミナルで実行します。

$npx skills add https://github.com/bxmaximum/bitrix-framework-skills --skill bitrix-catalog

インストール後、Claude Code で/bitrix-catalogを入力して読み込まれたか確認します。

詳細

商品カタログ(catalog)

基準:main 23.0+ · 検証済み:catalog 26.400.0、main 26.800.0

商品 ID = iblock 要素 ID です。iblock と catalog の読み込みが必要です。カート、注文、支払い → bitrix-sale、要素とプロパティ → bitrix-iblocks。

API の選択

必要な操作使用するもの
商品/価格/店舗の行を読み取るProductTable、PriceTable、StoreProductTable、CatalogIblockTable(ORM)
商品フィールド(数量、タイプ、VAT)を書き込むModel\Product::add/update — AVAILABLE、親 SKU のタイプ/在庫状況を再計算し、セット、サブスクリプションを設定します
価格を書き込むModel\Price::add/update/delete — PRICE_SCALE を計算し、通貨を検証し、親 SKU の価格を再集計します
カタログ iblock を登録するCCatalog::Add/Update(D7 の書き込み機能はありません)
レガシー、互換性の維持のみCCatalogProduct、CPrice、CCatalogSku ヘルパー

ProductTable/PriceTable に直接書き込まないでください。PRICE_SCALE を指定しない PriceTable::add() は検証に失敗し、直接書き込むと在庫状況や SKU の再計算が行われません。

カタログ iblock と SKU

\CCatalog::Add(['IBLOCK_ID' => $productIblockId]);                       // simple catalog
\CCatalog::Add([
    'IBLOCK_ID' => $offersIblockId,
    'PRODUCT_IBLOCK_ID' => $productIblockId,
    'SKU_PROPERTY_ID' => $skuPropertyId, // E property on the offers iblock, USER_TYPE = PropertyTable::USER_TYPE_SKU, LINK_IBLOCK_ID = products
]);
$info = \CCatalogSku::GetInfoByIBlock($iblockId); // CATALOG_TYPE, PRODUCT_IBLOCK_ID, IBLOCK_ID, SKU_PROPERTY_ID…

CATALOG_TYPE:CCatalogSku::TYPE_CATALOG(D、通常)、TYPE_PRODUCT(P、親のみ)、TYPE_OFFERS(O、オファー iblock)、TYPE_FULL(X、商品 + SKU 親)。商品のオファー:\CCatalogSku::getOffersList($productIds, $iblockId)。

商品タイプ ProductTable::TYPE_*:PRODUCT 1、SET 2、SKU 3(オファーを持つ親)、OFFER 4、FREE_OFFER 5(親を持たないオファー)、EMPTY_SKU 6、SERVICE 7(在庫管理なし)。購入するのはオファー(TYPE_OFFER)であり、SKU 親は購入しないでください。

use Bitrix\Catalog\Model\Product;
use Bitrix\Catalog\ProductTable;

$result = Product::update($elementId, [ // Product::add(['ID' => $elementId, 'TYPE' => ProductTable::TYPE_PRODUCT, …]) for a new row
    'QUANTITY' => 10,
    'QUANTITY_TRACE' => ProductTable::STATUS_YES,
    'CAN_BUY_ZERO' => ProductTable::STATUS_NO,
]);
if (!$result->isSuccess()) { /* $result->getErrorMessages() */ }

価格

価格タイプ:GroupTable(b_catalog_group)。基本タイプ:GroupTable::getBasePriceTypeId()(キャッシュ済み、?int)。タイプごとの閲覧/購入権限:GroupAccessTable。

use Bitrix\Catalog\GroupTable;
use Bitrix\Catalog\Model\Price;
use Bitrix\Catalog\PriceTable;

$result = Price::add([
    'PRODUCT_ID' => $elementId,
    'CATALOG_GROUP_ID' => GroupTable::getBasePriceTypeId(),
    'PRICE' => 1990.00,
    'CURRENCY' => 'RUB',   // must exist in the currency module
]);
if (!$result->isSuccess()) { /* $result->getErrorMessages() */ }

$prices = PriceTable::getList([
    'select' => ['ID', 'CATALOG_GROUP_ID', 'PRICE', 'CURRENCY', 'QUANTITY_FROM', 'QUANTITY_TO'],
    'filter' => ['=PRODUCT_ID' => $elementId],
])->fetchAll();

VAT は商品(VAT_ID、VAT_INCLUDED)に設定され、税率は VatTable にあります。最終購入者向けの価格と割引は PriceTable から読み取るのではなく、sale(bitrix-sale)で計算されます。

在庫と店舗

  • 商品レベル:ProductTable の QUANTITY、QUANTITY_RESERVED、QUANTITY_TRACE、CAN_BUY_ZERO、AVAILABLE。
  • 店舗:StoreTable + StoreProductTable(STORE_ID、PRODUCT_ID、AMOUNT、QUANTITY_RESERVED)。倉庫操作(入庫、移動、払出)は店舗ドキュメント(StoreDocumentTable、CCatalogDocs::conductDocument($docId, $userId) で実施。エラー時は false と $APPLICATION->GetException())を通じて行い、AMOUNT の直接編集や SQL は使用しないでください。
  • 店舗の権限(crm による在庫管理):ユーザーが閲覧できる内容と同じものを表示します。
use Bitrix\Catalog\Access\AccessController;
use Bitrix\Catalog\Access\ActionDictionary;
use Bitrix\Catalog\StoreProductTable;

$access = AccessController::getCurrent()
    ->getEntityFilter(ActionDictionary::ACTION_STORE_VIEW, StoreProductTable::class) ?? [];
$rows = StoreProductTable::getList([
    'select' => ['STORE_ID', 'AMOUNT', 'QUANTITY_RESERVED'],
    'filter' => [['=PRODUCT_ID' => $elementId], $access], // nested: an OR in user filter cannot bypass access
])->fetchAll();
  • catalog 26.400 以降 REST の catalog.storeproduct.list/get と catalog.document.element.list にこのフィルターが適用されます。アクセスが許可されていない店舗のドキュメント行では、STORE_FROM/STORE_TO/AMOUNT/PURCHASING_PRICE が null になり、これらのフィールドによるフィルタリングや並べ替えはできません。インテグレーションではこれらの値に依存しないでください。在庫行は管理者とレガシーモードではフィルタリングされません:AccessController::getCurrent()->isLegacyAccessMode()(catalog 26.400 以降。それ以前は !ModuleManager::isModuleInstalled('crm'))。旧バージョンでは REST 経由で全店舗が返されるため、インテグレーション側でフィルタリングしてください。

チェックリスト

  • iblock と catalog を読み込み、CCatalog::Add でカタログ iblock を登録し、PRODUCT_IBLOCK_ID + SKU_PROPERTY_ID を使用して SKU を設定する。
  • 商品と価格の書き込みには Model\Product/Model\Price を使用し、すべての Result を確認する。
  • 基本価格タイプには GroupTable::getBasePriceTypeId() を使用し、ID をハードコードしない。
  • バスケットには SKU 親ではなくオファーを追加する。
  • ユーザーに制限がある場合は店舗アクセスフィルターを使用して在庫を読み取り、直接 SQL は使用しない。
  • 読み取りはまとめて行う(ID を収集してクエリを 1 回実行)。ループ内で CCatalogProduct::GetByID を使用しない。

コメント