나는 당신이 그것을 어떻게했는지에 대한 호기심이 많은 조나단이다. 나는 당신의 접근 방식을 취하지 않았다. 내 것은 좀 더 복잡하다. 내 것은 다른 누군가가 URL에 쿠폰 코드를 올리는 것을 허용하지만 나는 쿠키와 그 모든 것을 설정합니다. 나는 기본적으로 사용자가 헤더에 자신의 양식을 설정하여 사용자가 쿠폰 코드에 입력하고 쿠폰을 전자 메일 캠페인의 URL에 넣을 수 있도록했습니다.
세부 사항으로 돌아가려면 시간이 걸릴 수 있으므로 조나단의 말처럼 오래 걸리는 데 도움이되는 코드 스 니펫을 게시 할 예정입니다.
카트 컨트롤러를 무시하고 자신의 동작을 추가하십시오.
public function couponExternalPostAction()
{
$quote = $this->_getQuote();
$couponCode = (string) $this->getRequest()->getParam('coupon_code');
$validateCoupon = Mage::getModel('package_module/coupon');
$json = $validateCoupon->addCouponCode($couponCode, $quote, $this->getRequest());
echo $json;
return;
}
정상적인 방법으로 제대로 작동하려면 couponPostAction()을 재정의해야했습니다.
나는 내 자신의 모델
public function addCouponCode($code, $quote, $request){
$couponCode = (string) $code;
$removed = false;
if ($request->getParam('remove') == 1) {
$couponCode = '';
$removed = true;
}
$oldCouponCode = $quote->getCouponCode();
/* No point in applying the rule again if it is the same coupon code that is in the quote */
if ($couponCode === $oldCouponCode) {
$json = $this->_getResponseJson($removed, $couponCode, $quote, false, true);
return $json;
}
// Set the code get the rule base on validation even if it doesn't validate (false), which will also add it to the session, then get our response
$quote->setCouponCode(strlen($couponCode) ? $couponCode : '');
$rule = $this->_validateCoupon($quote,$couponCode);
// add coupon code to cookie, so we can delete from quote if the user closes their browser and comes back
if($rule && !$removed){
Mage::getModel('core/cookie')->set('coupon_code', $couponCode, 0, '/', null, null, null, false);
}else{
Mage::getModel('core/cookie')->delete('coupon_code');
}
$json = $this->_getResponseJson($removed, $couponCode, $quote, $rule);
//See if the quote id is set before saving
$quoteId = $quote->getQuoteId();
//Save the quote since everything has been set if not the data wont be set on page refresh
$quote->save();
//Set the quote id if it wasn't set before saving the quote. This makes sure we work off the same quote and a new one isn't created.
if(empty($quoteId)){
$this->_setQuoteId($quote);
}
return $json;
}
검증
protected function _validateCoupon($quote,$couponCode){
$store = Mage::app()->getStore($quote->getStoreId());
$validator = Mage::getModel('package_module/validator');
$validator->init($store->getWebsiteId(), $quote->getCustomerGroupId(), $quote->getCouponCode());
return $validator->isValidExternalCode($couponCode, $quote->getShippingAddress(),false);
}
내가 내 자신의 검증 기능을 Mage_SalesRule_Model_Validator
을 연장 쿠폰
여기
public function isValidExternalCode($couponCode, $address, $setCoupon = true){
foreach ($this->_getRules() as $rule) {
if ($rule->getCode() && (in_array(strtolower($couponCode),explode(',',strtolower($rule->getCode()))))) {
if($setCoupon){
$address->setCouponCode($couponCode);
}
return $rule;
}
}
return false;
}
내가 JSON을 생성에 addCoupon 방법을 응답
rotected function _getResponseJson($removed, $couponCode, $quote, $rule = false, $isDup = false){
$json = '{"Response":{';
if($removed){
$json .= '"success":"Promotional code was cancelled successfully."';
Mage::getSingleton('checkout/session')->setData('coupon_rule',null);
}
if(!$removed && $isDup){
$json .= '"error":"' . $couponCode . ' is already applied"';
}else if(!$removed && $rule){
$json .= '"success":"Promotional code ' . $couponCode . ' has been applied",';
$json .= '"couponMessage":"<span>' . $rule->getName() . '</span>"';
Mage::getSingleton('checkout/session')->setData('coupon_rule','<span>' . $rule->getName() .'</span>');
}else if(!$removed){
$json .= '"error":"' . $couponCode . ' is not valid"';
$quote->setCouponCode('');
}
$json .= '}}';
return $json;
}
는 또한
public function collect(Mage_Sales_Model_Quote_Address $address)
{
Mage_Sales_Model_Quote_Address_Total_Abstract::collect($address);
$quote = $address->getQuote();
$store = Mage::app()->getStore($quote->getStoreId());
$eventArgs = array(
'website_id' => $store->getWebsiteId(),
'customer_group_id' => $quote->getCustomerGroupId(),
'coupon_code' => $quote->getCouponCode(),
);
$this->_calculator->init($store->getWebsiteId(), $quote->getCustomerGroupId(), $quote->getCouponCode());
$items = $address->getAllItems();
/* EDITS
* Moved the if statement for no items in cart down past these previous methods and then if the address type is shipping and the coupon is set
* add the coupon code to the address to allow the validation to still pick up the coupon code
*/
if($quote->getCouponCode() && ($address->getAddressType() == Mage_Sales_Model_Quote_Address::TYPE_SHIPPING)){
$address->setCouponCode($quote->getCouponCode());
}
if (!count($items)) {
return $this;
}
$address->setDiscountDescription(array());
foreach ($items as $item) {
if ($item->getNoDiscount()) {
$item->setDiscountAmount(0);
$item->setBaseDiscountAmount(0);
}
else {
/**
* Child item discount we calculate for parent
*/
if ($item->getParentItemId()) {
continue;
}
$eventArgs['item'] = $item;
Mage::dispatchEvent('sales_quote_address_discount_item', $eventArgs);
if ($item->getHasChildren() && $item->isChildrenCalculated()) {
foreach ($item->getChildren() as $child) {
$this->_calculator->process($child);
$eventArgs['item'] = $child;
Mage::dispatchEvent('sales_quote_address_discount_item', $eventArgs);
$this->_aggregateItemDiscount($child);
}
} else {
$this->_calculator->process($item);
$this->_aggregateItemDiscount($item);
}
}
}
/**
* Process shipping amount discount
*/
$address->setShippingDiscountAmount(0);
$address->setBaseShippingDiscountAmount(0);
if ($address->getShippingAmount()) {
$this->_calculator->processShippingAmount($address);
$this->_addAmount(-$address->getShippingDiscountAmount());
$this->_addBaseAmount(-$address->getBaseShippingDiscountAmount());
}
$this->_calculator->prepareDescription($address);
return $this;
}
모든 @Dan 코드를 게시하는 데 적합합니다. 나는 Cart 컨트롤러와 couponPostAction 메소드를 오버라이드하는 것에 대해 매우 염려 할 것입니다. 미래의 Magento 업그레이드 또는 패치가 사용자 정의로 인해 사이트를 손상시킬 수 있음을 의미합니다. 나는 당신이 그것을 피할 수 있다면 컨트롤러를 무시하지 말 것을 권한다. (이벤트 옵저버가 훨씬 좋다.) 내 솔루션에 대한 자세한 내용을 게시하여 키 컨트롤러를 재정의하지 않는 방법을 보여줍니다. –
처음 Magento에 들어갔을 때이 작업을 잠시 수행 했으므로 이제는 다르게 처리 할 것입니다. 이 상황은 특정 고객을 대상으로하며 업그레이드를 수행하려면 시작하기 전에 철저하게 품질 보증 테스트를 거쳐야한다는 점을 이해해야합니다. –
당신이 제어 할 수있는 것처럼 들리 겠지만, 나는 해결책을 읽고있는 Magento에게 새로운 사람일지도 모른다고 생각한다. –