Shared Catalog Architecture
Catalog Types
┌─────────────────â”
│ Public Catalog │ Default for all
└────────┬────────┘
│
┌────────▼────────â”
│ Shared Catalog │ Company-specific
│ (Custom) │ pricing & products
└────────┬────────┘
│
┌────────▼────────â”
│ Company Assigned│ Linked to companies
└─────────────────┘
Shared Catalog Repository
namespace Magento\SharedCatalog\Api;
interface SharedCatalogRepositoryInterface
{
public function get(int $catalogId): SharedCatalogInterface;
public function getList(SearchCriteriaInterface $searchCriteria): SharedCatalogSearchResultsInterface;
public function save(SharedCatalogInterface $catalog): SharedCatalogInterface;
public function delete(SharedCatalogInterface $catalog): bool;
}
Shared Catalog Interface
namespace Magento\SharedCatalog\Api\Data;
interface SharedCatalogInterface
{
public function getId(): ?int;
public function getName(): string;
public function getType(): string;
public function getCreatedById(): int;
public function getCreatedAt(): string;
public function getDescription(): ?string;
public function getStructureId(): int;
public function getPricingId(): int;
public function getCompaniesCount(): int;
}
Custom Pricing
Pricing Manager
namespace Vendor\B2B\Catalog\Pricing;
class SharedCatalogPricingManager
{
private PricingReaderInterface $pricingReader;
private PricingWriterInterface $pricingWriter;
public function setProductPrice(
int $catalogId,
int $productId,
float $price,
float $discount = 0
): void {
$pricingData = new PricingData([
'catalog_id' => $catalogId,
'product_id' => $productId,
'price' => $price,
'discount' => $discount,
'final_price' => $price - $discount,
]);
$this->pricingWriter->save($pricingData);
}
public function getProductPrice(
int $catalogId,
int $productId
): ?PricingData {
return $this->pricingReader->getByCatalogAndProduct(
$catalogId,
$productId
);
}
public function getCatalogPrices(int $catalogId): array
{
return $this->pricingReader->getAllByCatalog($catalogId);
}
}
Price Tier Configuration
namespace Vendor\B2B\Catalog\Pricing\Tier;
class PriceTierManager
{
public function setTiers(
int $catalogId,
int $productId,
array $tiers
): void {
foreach ($tiers as $tier) {
$tierData = new PriceTierData([
'catalog_id' => $catalogId,
'product_id' => $productId,
'qty_from' => $tier['qty_from'],
'qty_to' => $tier['qty_to'],
'price' => $tier['price'],
'discount' => $tier['discount'] ?? 0,
]);
$this->tierRepo->save($tierData);
}
}
public function getTiers(
int $catalogId,
int $productId
): array {
return $this->tierRepo->getByCatalogAndProduct(
$catalogId,
$productId
);
}
}
Catalog Assignment
Company-Catalog Assignment
namespace Vendor\B2B\Catalog\Assignment;
class CatalogAssignment
{
private CompanyRepositoryInterface $companyRepo;
public function assignCatalog(
int $companyId,
int $catalogId
): void {
$company = $this->companyRepo->get($companyId);
$company->setSharedCatalogId($catalogId);
$this->companyRepo->save($company);
}
public function unassignCatalog(int $companyId): void
{
$company = $this->companyRepo->get($companyId);
$company->setSharedCatalogId(null);
$this->companyRepo->save($company);
}
public function getCatalogCompanies(int $catalogId): array
{
return $this->companyRepo->getList(
$this->createSearchCriteria($catalogId)
)->getItems();
}
}
Catalog Permission Check
namespace Vendor\B2B\Catalog\Permission;
class CatalogPermissionChecker
{
public function canAccess(
int $customerId,
int $productId
): bool {
$customer = $this->customerRepo->getById($customerId);
$companyId = $customer->getCompanyId();
if (!$companyId) {
return false;
}
$company = $this->companyRepo->get($companyId);
$catalogId = $company->getSharedCatalogId();
if (!$catalogId) {
return false;
}
return $this->catalogProductRepo->exists($catalogId, $productId);
}
}
Catalog Synchronization
Catalog Sync Service
namespace Vendor\B2B\Catalog\Sync;
class CatalogSyncService
{
private SharedCatalogRepositoryInterface $catalogRepo;
private ProductRepositoryInterface $productRepo;
public function syncFromDefault(int $catalogId): SyncResult
{
$catalog = $this->catalogRepo->get($catalogId);
$result = new SyncResult();
// Get default catalog products
$defaultProducts = $this->getDefaultProducts();
foreach ($defaultProducts as $product) {
$exists = $this->catalogProductRepo->exists(
$catalogId,
$product->getId()
);
if (!$exists) {
$this->catalogProductRepo->addProduct(
$catalogId,
$product->getId()
);
$result->addAdded($product->getSku());
}
}
// Remove products not in default
$catalogProducts = $this->catalogProductRepo->getByCatalog($catalogId);
foreach ($catalogProducts as $catalogProduct) {
if (!$this->inDefault($catalogProduct->getProductId())) {
$this->catalogProductRepo->removeProduct(
$catalogId,
$catalogProduct->getProductId()
);
$result->addRemoved($catalogProduct->getSku());
}
}
return $result;
}
}
Price Sync
namespace Vendor\B2B\Catalog\Sync;
class PriceSyncService
{
public function syncPrices(
int $catalogId,
string $source
): void {
$prices = $this->priceSource->fetch($source, $catalogId);
foreach ($prices as $sku => $price) {
$product = $this->productRepo->get($sku);
$this->pricingManager->setProductPrice(
$catalogId,
$product->getId(),
$price
);
}
}
}
Quiz
1. What is a shared catalog?
2. How is pricing managed in shared catalogs?
3. What happens when a product is removed from the default catalog?
Flashcards
Question
What is a shared catalog?
Click to reveal answer
Answer
Company-specific catalog with custom pricing
Question
How does pricing work?
Click to reveal answer
Answer
Custom price per product per shared catalog
Question
What is catalog assignment?
Click to reveal answer
Answer
Linking a shared catalog to a company
Question
What is catalog sync?
Click to reveal answer
Answer
Updating shared catalog from default catalog
Revision Notes
Key Takeaways
- 1. Shared catalogs provide company-specific product selections
- 2. Custom pricing can be set per product per catalog
- 3. Companies are assigned to shared catalogs
- 4. Catalog sync keeps shared catalogs updated
- 5. Permissions control product visibility
Interview Tips
- • Explain shared catalog vs default catalog
- • Discuss custom pricing implementation
- • Describe catalog assignment workflow
- • Talk about catalog synchronization
Cheat Sheet
Shared Catalog:
Custom products + pricing
Assigned to companies
Synced from default catalog
Pricing:
Price per product per catalog
Tier pricing supported
Discounts configurable
Assignment:
Company → Shared Catalog
Controls product visibility