2011-01-31 3 views
1

여기와 Google에서 비슷한 질문을 많이하고 있습니다. 비슷한 것을 찾을 수 없다는 것에 놀랐습니다.Magento * Catalog * (장바구니가 아님) 가격을 쿠폰 코드로 새로 고치는 방법이 있습니까?

고객 그룹 및 계층화 된 가격 책정에 익숙하지만 고객이 설정 한 목표에 맞지 않습니다.

우리가 원하는 것은 사용자가 Magento 매장에 와서 정기적 인 가격으로 일반 홈페이지를 보는 것입니다. 이 시점에서 우리는 사용자가 쿠폰 코드를 추가하여 사이트가 새로 고쳐지고 정상 가격으로 표시된 할인 가격을 표시 할 수있는 눈에 잘 띄는 텍스트 필드를 원합니다 (또는 다른 시각적 방법에 의해 "slashed").

고객 그룹/계층 형 가격 책정은 고객이 로그인해야하므로 솔루션이 아닙니다. 모든 사용자가 할인을 볼 수 있으므로 NOT LOGGED IN 그룹도 도움이되지 않습니다.

이것은 장바구니에서 발생할 수 없습니다 너무 늦었 기 때문에 카탈로그 수준에서 발생해야합니다.

현재 OSCommerce를 사용 중이며 조만간 Magento로 전환하고 있습니다. g이 동작을 에뮬레이션하려면 사용자가 지역을 클릭하거나 쿠폰 코드를 입력 할 수있는 Store Access 페이지의 일반 웹 사이트에 텍스트 필드가 있어야합니다. 코드를 입력하면 특별 가격이있는 맞춤 상점으로 리디렉션됩니다.

저장소보기를 만든 다음 동일한 기능을 사용하여 Magento에서 현재의 방법을 다시 만들면 쉽지만 새 플랫폼으로 이동하는 것이 훨씬 강력하다는 생각이들 때 부끄러운 것처럼 보입니다.

이 작업을 수행하는 확장 프로그램을 보지 못했습니다. 이런 일이 성취 될 수 있는지에 대한 통찰력이있는 사람이 있습니까?

답변

2

나는 당신이 그것을 어떻게했는지에 대한 호기심이 많은 조나단이다. 나는 당신의 접근 방식을 취하지 않았다. 내 것은 좀 더 복잡하다. 내 것은 다른 누군가가 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; 
} 
+0

모든 @Dan 코드를 게시하는 데 적합합니다. 나는 Cart 컨트롤러와 couponPostAction 메소드를 오버라이드하는 것에 대해 매우 염려 할 것입니다. 미래의 Magento 업그레이드 또는 패치가 사용자 정의로 인해 사이트를 손상시킬 수 있음을 의미합니다. 나는 당신이 그것을 피할 수 있다면 컨트롤러를 무시하지 말 것을 권한다. (이벤트 옵저버가 훨씬 좋다.) 내 솔루션에 대한 자세한 내용을 게시하여 키 컨트롤러를 재정의하지 않는 방법을 보여줍니다. –

+1

처음 Magento에 들어갔을 때이 작업을 잠시 수행 했으므로 이제는 다르게 처리 할 것입니다. 이 상황은 특정 고객을 대상으로하며 업그레이드를 수행하려면 시작하기 전에 철저하게 품질 보증 테스트를 거쳐야한다는 점을 이해해야합니다. –

+0

당신이 제어 할 수있는 것처럼 들리 겠지만, 나는 해결책을 읽고있는 Magento에게 새로운 사람일지도 모른다고 생각한다. –

1

이것은 확실히 달성 할 수 있습니다. 쿠폰 필드의 값을 승인하고 해당 사용자에 대한 체크 아웃 세션을 시작하고 ($session = Mage::getSingleton('checkout/session')) 체크 아웃 세션 ($session->setData('coupon_code',$coupon)에 쿠폰 코드를 저장하는 컨트롤러로 사용자 정의 모듈 (시작 herehere)을 작성하는 작업이 포함됩니다.

그런 다음 세션에서 쿠폰 코드를 확인하기 위해 가격 모델을 확장하십시오. <rewrite> 구문을 사용하여 모듈에서 Mage_Catalog_Model_Product_Type_Price을 무시할 수 있습니다. 쿠폰 코드 ($couponCode = Mage::getSingleton("checkout/session")->getData("coupon_code");)를 검색하십시오. Price 객체는 Bundle과 다른 단순하지 않은 제품 유형과 다릅니다.

추가 정보가 필요하면 코드 샘플을 게시 할 수 있습니다.

+0

이런 일이 얼마나 복잡 Mage_SalesRule_Model_Quote_Discount의 수집 방법을 재정의했다? 나는 Magento (40 시간)로 매우 초록색이고 MVC 패러다임 (CodeIgniter를 가지고 노는 하루)을 이해하는 동안 초급 단계입니다. 프로그래머로서 그러나 나는 기꺼이 배우고 기꺼이 모든 노력을 다해 성공하거나 실패 하든지 내 "프로필"을 받으면 이것을 시도해 볼 수도 있습니다. 나는 누군가에게 나를 위해 그것을하도록 요구하는 것이 아닙니다. 나는 그 길을 따라 약간의 안내가있을 때 내가이 일을 할 합법적 인 기회가 있는지 알아 내려고하고있다. 코드 샘플은 훌륭합니다! – nero

+0

중간 정도의 복잡성을 가지고 있지만 Magento를 중장기 적으로 사용할 계획이라면 시작하는 것이 좋습니다. 익숙한 개념을 사용하면서 Magento의 코드 구조를 소개합니다. Magento는 학습 곡선을 가지고 있습니다 (많은 사람들이 그것에 대해 불평합니다). 그러나 일단 익숙하면 아키텍처는 사실 우아하고 반복성이 뛰어납니다. –

+0

최근 다른 요구 사항을 가진 작은 프로젝트를 만들었지 만 비슷한 접근 방식을 사용했습니다. 이를 위해 저는 요나단의 제안을 분명히 따라갈 것입니다. 여러 가지 맞춤 기능 향상 (예 :이 기능 포함)을해야하는 경우 Magento를 사용한 여행은 길고 혼란 스러울 것입니다. Magento는 엄청나게 구성 가능하며 "쉬운"사용자 정의를 위해 확장 가능합니다. 유일한 문제는 손쉬운 사용자 정의 중 일부는 엉덩이에 골치 아픈 고통이되고 오랜 시간이 걸리는 것입니다. 이것이 Jonathan이 Magento에 장기적으로 전념해야한다고 말한 이유입니다. – shaune