프레스토샵(PrestaShop)에서 상품 묶음 판매 기능 개발하기 🛍️🛒
안녕하세요, 여러분! 오늘은 정말 흥미진진한 주제로 여러분과 함께 이야기를 나눠볼 거예요. 바로 프레스토샵(PrestaShop)에서 상품 묶음 판매 기능을 개발하는 방법에 대해서요! 🎉 이 기능을 통해 우리 쇼핑몰은 한층 더 업그레이드될 거예요. 고객들에게 더 많은 선택지를 제공하고, 매출도 쑥쑥 올라갈 거라구요! ㅎㅎ
여러분, 혹시 재능넷(https://www.jaenung.net)이라는 사이트 아세요? 이곳은 다양한 재능을 거래할 수 있는 플랫폼인데요. 우리가 오늘 배울 내용도 이런 재능 중 하나가 될 수 있어요. 쇼핑몰 개발 능력이 있다면, 재능넷에서 그 능력을 공유하고 수익을 창출할 수도 있겠죠? 😊
자, 그럼 이제 본격적으로 시작해볼까요? 준비되셨나요? 고고씽~! 🚀
1. 프레스토샵(PrestaShop)이란? 🤔
먼저, 프레스토샵에 대해 간단히 알아볼까요? 프레스토샵은 오픈소스 e-커머스 솔루션이에요. 쉽게 말해, 온라인 쇼핑몰을 만들 수 있게 해주는 프로그램이죠. PHP로 작성되어 있고, MySQL 데이터베이스를 사용해요.
프레스토샵의 주요 특징:
- 무료로 사용 가능한 오픈소스 솔루션
- 다양한 테마와 모듈 지원
- 다국어 및 다중 통화 지원
- SEO 최적화
- 모바일 친화적인 디자인
프레스토샵은 정말 강력한 기능들을 제공하지만, 오늘 우리가 만들어볼 '상품 묶음 판매' 기능은 기본적으로 제공되지 않아요. 그래서 우리가 직접 개발해볼 거예요! 😎
이 기능을 개발하면서 우리는 프레스토샵의 구조를 더 깊이 이해하고, PHP 프로그래밍 실력도 향상시킬 수 있을 거예요. 마치 재능넷에서 새로운 재능을 습득하는 것처럼 말이죠! 🌟
위 그림에서 볼 수 있듯이, 프레스토샵은 프론트엔드, 백엔드, 데이터베이스, 그리고 이들을 연결하는 모듈 시스템으로 구성되어 있어요. 우리가 만들 상품 묶음 판매 기능은 이 모든 부분에 걸쳐 작업이 필요할 거예요. 흥미진진하지 않나요? 😄
자, 이제 기본적인 이해는 됐으니 본격적으로 개발을 시작해볼까요? 다음 섹션에서는 상품 묶음 판매 기능의 개념과 설계에 대해 알아볼 거예요. 준비되셨나요? Let's go! 🏃♂️💨
2. 상품 묶음 판매 기능의 개념과 설계 🎨
여러분, 상품 묶음 판매가 뭔지 아시나요? 간단히 말해서, 여러 개의 상품을 하나의 패키지로 묶어서 판매하는 거예요. 예를 들어, 노트북과 마우스, 키보드를 세트로 판매한다든지, 화장품 세트를 만들어 판매하는 거죠. 이런 기능이 왜 필요할까요? 🤔
상품 묶음 판매의 장점:
- 고객에게 더 많은 가치 제공
- 재고 관리 효율성 증가
- 평균 주문 금액 상승
- 관련 상품 판매 증가
- 특별한 프로모션 기회 제공
이렇게 좋은 기능을 우리 쇼핑몰에 추가한다면, 매출이 쑥쑥 올라갈 거예요! 😎 그럼 이제 이 기능을 어떻게 설계할지 생각해볼까요?
2.1 기능 요구사항 정의
먼저, 우리가 만들 상품 묶음 판매 기능이 어떤 기능들을 가져야 할지 정의해봐요.
- 관리자가 여러 상품을 선택해서 묶음 상품을 만들 수 있어야 해요.
- 묶음 상품에 대한 할인율을 설정할 수 있어야 해요.
- 고객은 묶음 상품을 한 번에 장바구니에 담을 수 있어야 해요.
- 묶음 상품의 재고는 개별 상품의 재고와 연동되어야 해요.
- 묶음 상품 페이지에서는 포함된 개별 상품 정보도 볼 수 있어야 해요.
우와, 생각보다 고려할 게 많네요! 하지만 걱정 마세요. 하나씩 차근차근 해결해 나갈 거예요. 👍
2.2 데이터베이스 설계
이제 이 기능을 구현하기 위해 어떤 데이터베이스 테이블이 필요한지 생각해볼까요?
필요한 테이블:
- ps_product_bundle: 묶음 상품 정보를 저장할 테이블
- ps_product_bundle_item: 묶음 상품에 포함된 개별 상품 정보를 저장할 테이블
이 테이블들의 구조를 SQL로 표현하면 다음과 같아요:
CREATE TABLE ps_product_bundle (
id_bundle INT AUTO_INCREMENT PRIMARY KEY,
name VARCHAR(255) NOT NULL,
description TEXT,
discount_percentage DECIMAL(5,2),
active TINYINT(1) DEFAULT 1,
date_add DATETIME,
date_upd DATETIME
);
CREATE TABLE ps_product_bundle_item (
id_bundle_item INT AUTO_INCREMENT PRIMARY KEY,
id_bundle INT,
id_product INT,
quantity INT DEFAULT 1,
FOREIGN KEY (id_bundle) REFERENCES ps_product_bundle(id_bundle),
FOREIGN KEY (id_product) REFERENCES ps_product(id_product)
);
우와~ 이렇게 테이블을 만들면, 묶음 상품 정보와 그에 포함된 개별 상품 정보를 깔끔하게 저장할 수 있겠죠? 😊
2.3 모듈 구조 설계
이제 이 기능을 프레스토샵 모듈로 만들어볼 거예요. 프레스토샵 모듈의 기본 구조는 다음과 같아요:
각 파일과 디렉토리의 역할은 다음과 같아요:
- productbundle.php: 모듈의 메인 클래스 파일
- config.xml: 모듈 설정 정보
- views/: 프론트엔드와 백엔드의 템플릿 파일들
- controllers/: 프론트엔드와 백엔드의 컨트롤러 파일들
- classes/: 모델 클래스 파일들
- sql/: 데이터베이스 관련 SQL 파일들
이렇게 구조를 잡으면, 우리의 상품 묶음 판매 기능을 깔끔하게 구현할 수 있을 거예요. 😎
자, 여기까지 상품 묶음 판매 기능의 개념과 설계에 대해 알아봤어요. 어때요? 생각보다 복잡하지만 재미있죠? 이제 다음 섹션에서는 실제로 이 기능을 구현해볼 거예요. 준비되셨나요? 코딩의 세계로 고고씽~! 🚀👨💻
3. 상품 묶음 판매 기능 구현하기 💻
자, 이제 본격적으로 코딩을 시작해볼까요? 여러분, 긴장되나요? 걱정 마세요! 우리 함께 차근차근 해나가면 어렵지 않을 거예요. 마치 재능넷에서 새로운 재능을 배우는 것처럼 말이죠! 😉
3.1 모듈 기본 구조 만들기
먼저, 우리 모듈의 기본 구조를 만들어볼게요. 프레스토샵의 modules 디렉토리에 'productbundle'이라는 새 폴더를 만들고, 그 안에 다음 파일들을 생성해주세요.
modules/
└── productbundle/
├── productbundle.php
├── config.xml
├── index.php
├── views/
│ ├── templates/
│ │ ├── admin/
│ │ └── front/
│ └── index.php
├── controllers/
│ ├── admin/
│ ├── front/
│ └── index.php
├── classes/
│ └── index.php
└── sql/
└── index.php
우와~ 폴더 구조가 꽤 복잡해 보이죠? 하지만 걱정 마세요. 각 폴더와 파일의 역할을 하나씩 살펴볼게요. 😊
3.2 productbundle.php 파일 작성하기
이제 모듈의 메인 클래스 파일인 productbundle.php를 작성해볼게요. 이 파일은 모듈의 설치, 제거, 업그레이드 등의 기능을 담당해요.
<?php
if (!defined('_PS_VERSION_')) {
exit;
}
class ProductBundle extends Module
{
public function __construct()
{
$this->name = 'productbundle';
$this->tab = 'front_office_features';
$this->version = '1.0.0';
$this->author = 'Your Name';
$this->need_instance = 0;
$this->ps_versions_compliancy = array('min' => '1.7', 'max' => _PS_VERSION_);
$this->bootstrap = true;
parent::__construct();
$this->displayName = $this->l('Product Bundle');
$this->description = $this->l('Allows you to create and sell product bundles.');
$this->confirmUninstall = $this->l('Are you sure you want to uninstall?');
}
public function install()
{
include(dirname(__FILE__).'/sql/install.php');
return parent::install() &&
$this->registerHook('displayAdminProductsExtra') &&
$this->registerHook('displayProductAdditionalInfo') &&
$this->registerHook('actionProductAdd') &&
$this->registerHook('actionProductUpdate') &&
$this->registerHook('actionProductDelete');
}
public function uninstall()
{
include(dirname(__FILE__).'/sql/uninstall.php');
return parent::uninstall();
}
// 여기에 추가적인 메서드들이 들어갈 거예요!
}
우와~ 꽤 긴 코드죠? 하지만 걱정 마세요. 하나씩 설명해드릴게요! 😄
- __construct() 메서드: 이 메서드는 모듈이 생성될 때 호출돼요. 모듈의 기본 정보를 설정하는 역할을 해요.
- install() 메서드: 모듈이 설치될 때 실행돼요. 데이터베이스 테이블을 생성하고, 필요한 훅(hook)들을 등록해요.
- uninstall() 메서드: 모듈이 제거될 때 실행돼요. 데이터베이스 테이블을 삭제하는 등의 정리 작업을 수행해요.
이제 기본 구조가 완성됐어요! 다음으로 우리의 상품 묶음 기능을 구현하는 메서드들을 추가해볼까요?
3.3 상품 묶음 관리 기능 구현하기
이제 관리자가 상품 묶음을 만들고 관리할 수 있는 기능을 추가해볼게요. productbundle.php 파일에 다음 메서드들을 추가해주세요.
public function hookDisplayAdminProductsExtra($params)
{
$product_id = $params['id_product'];
$bundles = $this->getBundlesForProduct($product_id);
$this->context->smarty->assign(array(
'bundles' => $bundles,
'product_id' => $product_id,
));
return $this->display(__FILE__, 'views/templates/admin/product_tab.tpl');
}
private function getBundlesForProduct($product_id)
{
$query = new DbQuery();
$query->select('pb.*, pbi.quantity')
->from('product_bundle', 'pb')
->innerJoin('product_bundle_item', 'pbi', 'pb.id_bundle = pbi.id_bundle')
->where('pbi.id_product = '.(int)$product_id);
return Db::getInstance()->executeS($query);
}
public function hookActionProductAdd($params)
{
$this->updateProductBundles($params['id_product']);
}
public function hookActionProductUpdate($params)
{
$this->updateProductBundles($params['id_product']);
}
private function updateProductBundles($product_id)
{
if (Tools::isSubmit('product_bundles')) {
$bundles = Tools::getValue('product_bundles');
// 기존 번들 삭제
Db::getInstance()->delete('product_bundle_item', 'id_product = '.(int)$product_id);
foreach ($bundles as $bundle) {
$id_bundle = $bundle['id_bundle'];
$quantity = $bundle['quantity'];
// 새 번들 추가
Db::getInstance()->insert('product_bundle_item', array(
'id_bundle' => (int)$id_bundle,
'id_product' => (int)$product_id,
'quantity' => (int)$quantity,
));
}
}
}
우와~ 코드가 많아 보이죠? 하지만 각 메서드의 역할을 이해하면 그리 어렵지 않아요! 😊
- hookDisplayAdminProductsExtra(): 관리자 상품 페이지에 상품 묶음 관리 탭을 추가해요.
- getBundlesForProduct(): 특정 상품이 포함된 모든 묶음을 가져와요.
- hookActionProductAdd() 와 hookActionProductUpdate(): 상품이 추가되거나 수정될 때 상품 묶음 정보를 업데이트해요.
- updateProductBundles(): 실제로 상품 묶음 정보를 데이터베이스에 저장하는 역할을 해요.
이제 관리자가 상품 묶음을 만들고 관리할 수 있는 기본적인 기능이 완성됐어요! 👏
3.4 프론트엔드 표시 기능 구현하기
이제 고객들이 상품 페이지에서 묶음 상품을 볼 수 있도록 해볼까요? productbundle.php 파일에 다음 메서드를 추가해주세요.
public function hookDisplayProductAdditionalInfo($params)
{
$product_id = $params['product']['id_product'];
$bundles = $this->getBundlesForProduct($product_id);
if (!empty($bundles)) {
$this->context->smarty->assign(array(
'bundles' => $bundles,
'product_id' => $product_id,
));
return $this->display(__FILE__, 'views/templates/front/product_bundles.tpl');
}
return '';
}
이 메서드는 상품 페이지에 상품 묶음 정보를 표시해줘요. 멋지죠? 😎
3.5 템플릿 파일 만들기
마지막으로, 우리가 만든 기능을 실제로 화면에 표시할 템플릿 파일을 만들어볼게요. views/templates/admin/ 폴더에 product_tab.tpl 파일을, views/templates/front/ 폴더에 product_bundles.tpl 파일을 만들어주세요.
product_tab.tpl:
<div class="panel product-tab">
<h3>{l s='Product Bundles' mod='productbundle'}</h3>
<div class="form-group">
<label class="control-label col-lg-3">
{l s='Select bundles for this product' mod='productbundle'}
</label>
<div class="col-lg-9">
{foreach $bundles as $bundle}
<div class="checkbox">
<label>
<input type="checkbox" name="product_bundles[{$bundle.id_bundle}][id_bundle]" value="{$bundle.id_bundle}" {if $bundle.id_product == $product_id}checked="checked"{/if}>
{$bundle.name}
</label>
<input type="number" name="product_bundles[{$bundle.id_bundle}][quantity]" value="{$bundle.quantity|default:1}" min="1">
</div>
{/foreach}
</div>
</div>
</div>
product_bundles.tpl:
<div class="product-bundles">
<h3>{l s='Product Bundles' mod='productbundle'}</h3>
{foreach $bundles as $bundle}
<div class="bundle-item">
<h4>{$bundle.name}</h4>
<p>{$bundle.description}</p>
<p>{l s='Discount:' mod='productbundle'} {$bundle.discount_percentage}%</p>
<button class="btn btn-primary add-to-cart-bundle" data-id-bundle="{$bundle.id_bundle}">
{l s='Add bundle to cart' mod='productbundle'}
</button>
</div>
{/foreach}
</div>
우와~ 이제 정말 완성이 눈앞에 보이네요! 😃
3.6 마무리
자, 이제 우리의 상품 묶음 판매 기능이 거의 완성되었어요! 마지막으로 몇 가지 작업만 더 해주면 돼요. 함께 마무리해볼까요? 😊
3.6 장바구니 기능 구현하기
고객이 상품 묶음을 장바구니에 담을 수 있도록 해야겠죠? productbundle.php 파일에 다음 메서드를 추가해주세요.
public function hookActionCartSave($params)
{
$cart = $params['cart'];
$id_bundle = Tools::getValue('id_bundle');
if ($id_bundle) {
$bundle_items = $this->getBundleItems($id_bundle);
foreach ($bundle_items as $item) {
$cart->updateQty($item['quantity'], $item['id_product']);
}
}
}
private function getBundleItems($id_bundle)
{
$query = new DbQuery();
$query->select('id_product, quantity')
->from('product_bundle_item')
->where('id_bundle = '.(int)$id_bundle);
return Db::getInstance()->executeS($query);
}
이 코드는 고객이 묶음 상품을 장바구니에 담을 때, 묶음에 포함된 모든 상품을 자동으로 장바구니에 추가해줘요. 멋지죠? 😎
3.7 JavaScript 추가하기
이제 프론트엔드에서 "Add bundle to cart" 버튼이 클릭되었을 때 실제로 장바구니에 상품을 추가하는 JavaScript 코드를 작성해볼게요. views/js/ 폴더를 만들고 그 안에 front.js 파일을 생성해주세요.
$(document).ready(function(){
$('.add-to-cart-bundle').click(function(e){
e.preventDefault();
var idBundle = $(this).data('id-bundle');
$.ajax({
type: 'POST',
url: prestashop.urls.base_url + 'module/productbundle/addtocart',
data: {
id_bundle: idBundle,
action: 'add-bundle-to-cart',
ajax: true
},
success: function(resp){
// 성공 메시지 표시
prestashop.emit('updateCart', {reason: {idProduct: idBundle, idProductAttribute: 0, linkAction: 'add-to-cart'}});
},
error: function(resp){
// 에러 메시지 표시
}
});
});
});
이 JavaScript 코드는 "Add bundle to cart" 버튼이 클릭되면 AJAX 요청을 보내 장바구니에 상품 묶음을 추가해요. 그리고 장바구니 업데이트 이벤트를 발생시켜 화면에 반영되도록 해줘요.
3.8 컨트롤러 추가하기
마지막으로, AJAX 요청을 처리할 컨트롤러를 추가해볼게요. controllers/front/ 폴더에 AddToCartController.php 파일을 생성하고 다음 코드를 추가해주세요.
<?php
class ProductBundleAddToCartModuleFrontController extends ModuleFrontController
{
public function initContent()
{
parent::initContent();
$id_bundle = Tools::getValue('id_bundle');
$cart = $this->context->cart;
if ($id_bundle) {
$bundle_items = $this->module->getBundleItems($id_bundle);
foreach ($bundle_items as $item) {
$cart->updateQty($item['quantity'], $item['id_product']);
}
$this->ajaxDie(json_encode([
'success' => true,
'message' => $this->l('Bundle added to cart successfully')
]));
} else {
$this->ajaxDie(json_encode([
'success' => false,
'message' => $this->l('Failed to add bundle to cart')
]));
}
}
}
이 컨트롤러는 AJAX 요청을 받아 실제로 장바구니에 상품 묶음을 추가하는 역할을 해요.
3.9 최종 점검
자, 이제 모든 코드가 완성되었어요! 🎉 마지막으로 다음 사항들을 확인해주세요:
- 모듈이 정상적으로 설치되고 활성화되었는지 확인
- 관리자 페이지에서 상품 묶음을 생성하고 관리할 수 있는지 확인
- 프론트엔드 상품 페이지에서 상품 묶음 정보가 올바르게 표시되는지 확인
- "Add bundle to cart" 버튼을 클릭했을 때 장바구니에 상품 묶음이 정상적으로 추가되는지 확인
모든 것이 정상적으로 작동한다면, 축하드려요! 🎊 여러분은 방금 프레스토샵에 상품 묶음 판매 기능을 성공적으로 추가했어요!
마무리
이렇게 해서 우리의 상품 묶음 판매 기능 개발이 모두 끝났어요. 어떠셨나요? 처음에는 복잡해 보였지만, 하나씩 차근차근 해나가니 그리 어렵지 않았죠? 😊
이 과정을 통해 여러분은 프레스토샵의 모듈 개발 방법, PHP 프로그래밍, 데이터베이스 관리, 프론트엔드 개발 등 다양한 웹 개발 기술을 배우셨을 거예요. 마치 재능넷에서 새로운 재능을 습득한 것처럼 말이죠!
이제 여러분의 쇼핑몰은 더욱 강력해졌어요. 고객들에게 더 다양한 선택지를 제공하고, 매출도 늘어날 거예요. 앞으로도 계속해서 새로운 기능을 추가하고 개선해 나가세요. 여러분의 쇼핑몰이 점점 더 성장하는 모습을 보게 될 거예요! 💪🚀
코딩은 끝났지만, 여러분의 여정은 여기서 끝이 아니에요. 이 경험을 바탕으로 더 많은 것을 배우고 성장하세요. 여러분의 앞날을 응원합니다! 화이팅! 😄👍