Coder Social home page Coder Social logo

silvershop-discounts's People

Contributors

anhld avatar benjicarson avatar bummzack avatar christopherbolt avatar chromos33 avatar djmattski avatar fonsekaean avatar gordonbanderson avatar igornadj avatar jedateach avatar madmatt avatar markguinn avatar oliver-norden avatar pmhou avatar shoosah avatar sn4h avatar sparkcom avatar sunnysideup avatar thebnl avatar wernerkrauss avatar wilr avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar

silvershop-discounts's Issues

Specific pricing error

Hello ,

got the following error. I am using SS4. Wonder if there is a way around it.

[Recoverable Error] Argument 1 passed to SilverShop\Discounts\Model\SpecificPrice::filter() must be an instance of SilverStripe\ORM\DataList, instance of SilverStripe\ORM\UnsavedRelationList given, called in /home/xxx/vendor/silvershop/discounts/src/Extensions/ProductSpecificPricingExtension.php on line 37

Applied Member Group Discount Prevents Checkout

Hi Guys,

I had recently upgraded my site (including the silvershop-discounts module) and have come across a strange error / issue having now narrowed it down to what I believe is this module.

Previously using Silverstipe 3.6.3, Silvershop 2.3.1, silvershop-discounts 1.2.0 - no discount issue.
Currently using Silverstipe 3.7.3, Silvershop 2.4.2, silvershop-discounts 1.3.1

The issue occurs if a logged in member (not admin), that has a group discount applied is in the checkout process (note: I am using a stepped checkout). For some reason the checkout form action acquires a ?stage=Stage suffix.

Because these members are not admin the form submission redirects the user to an admin login page / prevents the user from continuuing the checkout process.

If the discount is removed for that member group then the suffix is not applied and the user is able to checkout as normal.

Any clues / fixes?

Referral rewards

Members could earn store credit by referring others to the shop via a generated code. This code could be entered at the checkout, or be incorporated into a link.

When an order is completely paid for, the commission can be worked out, and credited to the referrer's account.

Adding a discount to the used code would give more incentive for people to take the referral, however this would come at a greater cost to the shop owner.

This may be suitable as a completely separate submodlue, or possibly even a silverstripe module.

Coupon stacking configuration

Currently you can only ever choose one coupon per order. The system would be flexible if you could stack coupons in various ways. Obviously this is a business decision, and should be up to the business owner how they want to be able to apply coupons.

Here's an article that talks about various stacking policies:
http://lifehacker.com/seven-retailers-that-let-you-stack-coupons-1484256706?utm_campaign=socialflow_lifehacker_facebook&utm_source=lifehacker_facebook&utm_medium=socialflow

OrderDiscountModifier bug

    {
        return implode(",",
            $this->Order()->Discounts()
                ->filter("Code:not", "")
                ->map('ID', 'Title')
        );
    }

In the above codes, the implode function will throw error when the array returned is null.

regards,

Discounts added to orders, when viewing in ModelAdmin

We believe we have found a bug, that causes coupons to be applied to all orders viewed in backend/Orders modeladmin.
Can someone test and see if they get the same result please.

Steps to reproduce:

  1. Log in as an administrator
  2. Go to the frontend of shop
  3. Add a product to cart
  4. Go to checkout page and apply a coupon code - leave the page open
  5. Now in a new tab, go and visit a order in backend - the selected coupon code is applied to the order

(Coupon percentage based, applies per item, only Product Types "Product")

adding order modifier

Hi there,

There is every chance i am doing this wrong but when i add,

Order::set_modifiers(array(
        "OrderCouponModifier"
    ));

to my shop _config file i get,

Fatal error: Call to undefined method Order::set_modifiers() in ...

ok i think i may have got passed this point, i added

Order:
  modifiers:
    - 'OrderCouponModifier'

to my config.yml and now it doesnt error but when i click on the apply coupon button at checkout i get a white page of death.

in the error logs im getting,

PHP Fatal error:  Call to undefined method ShoppingCart::getInstance()

any ideas?

Mick

GiftVoucherProduct Issues

I am having a few issues with using the Gift Vouchers, I am not sure if there is anything I need to add to config.yml to make it work correctly. Currently I have:

Order:
modifiers:
- 'OrderDiscountModifier'
CheckoutPage:
steps:
'membership': 'CheckoutStep_Membership'
'contactdetails': 'CheckoutStep_ContactDetails'
'shippingaddress': 'CheckoutStep_Address'
'billingaddress': 'CheckoutStep_Address'
'shippingmethod': 'CheckoutStep_ShippingMethod'
'discount' : 'CheckoutStep_Discount'
'paymentmethod': 'CheckoutStep_PaymentMethod'
'summary': 'CheckoutStep_Summary'

Some of the problems are:

  1. I get this error message: Cannot access property GiftVoucherProduct::$global_allow_purchase from line 38 of GiftVoucherProduct
  2. Gift vouchers are not purchaseable. The database does not save the value in 'Allow product to be purchased'. If I try to add them to a cart I get an error that tells me they can't be purchased. Looing in the database the value for 'AllowPurchase' is 1
  3. I also get the message that 'Form' is not an allowed action on GiftVoucherProduct_Controller

If I add this to GiftVoucherProduct:
private static $global_allow_purchase = true;

And add 'Form' as an allowed action on the controller, the problems go away. So I am not sure if I have missed configuring something correctly to make it run without me having to modify the code.

Restructure constraints system to be less confusing

Currently DiscountConstraint extends DataExtension. This was merely to encapsulate the additional db / relation fields that need be extended on a Discount. Also encapsulated is the checking functions that look at those fields and decide if an order/item is within the constraint.

The problem is that it is quite messy. These classes are being instantiated on their own, with functions that are used quite statically. If one of the check or filter functions is called on a $discount object, then it will call only one of the constraints function's.

A restructuring could look like this:

BlahConstraint extends DiscountConstraint{

   //has this constraint been added to the given discount
   //we automatically skip constraints that haven't been configured during checking
   function applies(){
      return $this->discount->FooList()->exists();
   }

   //does the order comply with this constraint
   function check(){
       //check if (something to do with the order) exists within FooList
   }

   //function filter(DataList $discounts) should be optional

}

BlahConstraint_DiscountExtension extends DiscountConstraintExtension{

   private static $has_many = array(
       'FooList' => 'Foo'
   );

}

// elsewhere the DiscountConstraintExtensions are applied, based on a configured list of DiscountConstraints

Coupon & Cart Discounts should be listed in the Cart Table and Summary Step Table

Do we have something like
<% loop Discounts %> or should it be part of <% loop Modifiers %> ???

eg:

<% with Cart %>
    <table class="table">
        <tfoot>
            <% loop Modifiers %>
                <% if ShowInTable %>
            <tr class="modifierRow $EvenOdd $FirstLast $Classes">
                <td colspan="3">$TableTitle</td>
                <td>$TableValue.Nice</td>
            </tr>
                <% end_if %>
            <% end_loop %>
            <% loop Discounts %> <!-- ?????? -->
                <% if ShowInTable %>
            <tr class="modifierRow $EvenOdd $FirstLast $Classes">
                <td colspan="3">$TableTitle</td>
                <td>$TableValue.Nice</td>
            </tr>
                <% end_if %>
            <% end_loop %>
            <tr>
                <th colspan="3">Grand Total</th>
                <td>$Total.Nice $Currency</td>
            </tr>
        </tfoot>
    </table>
<% end_with %>

Is it maintained?

Not sure if this module is maintained anymore or not.
I'm getting a timeout error on loading /admin/discounts page. No errors in dev/build.

Silvershop code version - ^3@dev
SilverStripe version - 4.3.0@stable

Before & After prices in templates

Hello

I've created a Discount and added some products to it, that should be affected by this discount. What is the smartest way to create Before/after prices in templates to reflect the discount the customer will receive?

Multiple cart-level discounts results in discount greater than total

When the discount is greater than the total, you get negative order totals.

If you have two+ cart total discounts they may both be applied to the subtotal, and therefore add up to greater than the subtotal. This is a motivation to switch to cart-level discounts actually applying to individual items.
Or another approach is to apply cart level discounts to whatever is left after item discounts have been applied?

See Calculator.php https://github.com/burnbright/silverstripe-shop-discount/blob/master/code/Calculator.php#L31

If orders get through with this bug, then it may turn out that discounts are counted because they are linked to the order, yet the total discounted amount will still be greater than the order value.

Coupon remove

Hi:
After applied a coupon code, the coupon form shows 2 buttons.

"Apply coupon" and "remove coupon".

if clicks on "Remove coupon", even coupon on admin area removed.

How to duplicate:

1> create a coupon on discount -> coupon tab
2> buy some thing and go to checkout page.
3> apply coupon.
4> remove coupon.
5>go back to admin discount panel , and coupon just created was removed.

Also, how can i apply a coupon at same time show a discount? it seems coupon overwrite
discount price on checkout form.

Any coupon applied 2 times

Hi.

Anytime I create a coupon, everything works fine except the coupon is applied 2 times on the order. This happens for every coupon types and on every product.

I'm using a fresh installation of SS4 by the way, I guess it comes from that but I'm not quite sure how to fix it.

Purchaseable gift vouchers

Customers specify a giftable amount, and a special discount code item is added to their cart.

Upon order completion, the discount code is emailed to the user, or alternatively to a specified email, with a greeting message.

OrderItem_GiftVoucher

  • has_one Coupon

The actual gift voucher (coupon) should be generated when the order is fully paid for. It can be linked to the OrderItem_GiftVoucher.

Discounts pr. default applies to all orders

Hi. Just had some unexpected results on a very old SS3 installation. Basically the issue is that all discounts defaults to apply to all orders, if no constrain is found.
In this case, the client created products constraint of a list of products. These products where not translated (we use fluent), so for the locales where the constraint products where not translated, the discount got applied to all orders :-(
Not sure if this is still an issue in never versions, but if it is, i think we need some kind of "flag" like, "no constraints, applies to all orders".
Having a discount that falls-back to applying to all orders seems a bit scary.
Is this still how it works in newer versions, or has that been changed?

Ability to add more than one coupon per order

Allowing multiple coupons will require the system to decide which coupons will be used for which parts of the order.

With the way that discounts are calculated, this shouldn't be impossible, but it probably also won't be very simple.

Coupon Report

Coupons greatly help to monitor offline / external sales efforts. The shop discount module should maximise the information that comes from sales made with coupons.

Things that may be useful to track:

  • $ sales by coupon
  • Number of uses per coupon (+ % of limit, if applicable)
  • Orders for a particular coupon
  • Track if an individual code was used
  • Graph usage over time

Fix SS4 install via composer

Same issue as silvershop/silvershop-comparison#9, this module has an unrestricted requirement for silvershop/core in the only released version (e.g. 1.3.0), meaning that composer pulls that before checking dev-master.

For this one, just updating the 1.3.0 version with a new 1.3.1 that targets silvershop/core <3 would suffice.

Add module to scrutinizer

Could you please add the module to scrutinizer? https://scrutinizer-ci.com/g/new. We're keeping track of all modules we use on our contributions dashboard (github-dashing.herokuapp.com), and I've added scrutinizer quality and coverage scores there. Doesn't require any config, just four clicks. You'll have to click "Schedule inspection" for the first run, after that it should kick off automatically on commits.

There's banners you can copy paste into your README if you want. Also, if you feel like it, you could also add me as a collaborator :) There's a "Add collaborators to your repository" option on the homepage.

We're experimenting with a more fine tuned config, including code coverage running on travis, but that's not really to roll out yet (https://github.com/stojg/silverstripe-timeline). Happy to hear feedback and get help of course :)

Cumulative coupons: use in conjunction with others, or not

Currently when you enter a coupon code, it will overwrite any coupon that is already set. It should be optional for coupons to be used in conjuction with others. Particularly when two coupons may apply to specific products.

TODO:

  • Add cumulative boolean field to OrderCoupon
  • Create a new modifier per coupon
  • Remove all other coupons if a non-cumulative coupon is added
  • Remove cumulative coupon if another coupon is added
  • Prevent the same coupon being added twice

[SS4] DiscountConstraint subclass db fields not being created + fix

Hi,

In my local SS4 system the db fields from the various DiscountConstraint subclasses weren't being created. I couldn't figure out why, but I changed some code to fix things.

In a nutshell, the db fields are created when the constraints are added using extensions: in the module's config.yml instead of constraints: in config.yml + DiscountConstraint::set_up_constraints() in the module's _config.php.

My 'fix' is in this commit, which I feel is worth merging, but I'm not sure if it might impact anything else... or if I'm just hacking around a more underlying issue...?

Thanks,
Grant

Fatel Error : Cannot access property GiftVoucherProduct::$global_allow_purchase

GiftVoucherProduct.php on line 37

public function canPurchase($member = null, $quantity = 1) { if(!self::$global_allow_purchase){ return false; }
in my Composer

"silvershop/core": "^2.2", "silvershop/discounts": "^1.2",

In Product class this property is private. Product.php

We shall either remove this function so we can rely on core class function or this need to alter accordingly.

Generic discounting system

A order discount rules system will help to automatically provide discounts in complex ways, without coupons.

I'm now going to be working on a more generic system. This will mean abstracting out some of the coupon functionality and applying it to the cart, without the need to enter a coupon.

Discounts could apply to: products, cart items, cart subtotals. I've tried to illustrate this here.

Some ideas of what I'd hope to achieve:

  • Free shipping on orders over $75, during Christmas
  • % discount for specific members, or member groups
  • Discount for countries, regions, zones
  • Category / apparel discounts
  • Store specific discount
  • Pick-up in store, and save $5
  • Pay by bank wire and get 2% off
  • Buy x , get y free
  • Pay less when x,y,z are purchased together
  • Get 25% off your second pair of shoes

Its easy to see that conflicting discounts may arise. In some cases store owners may want to prevent stacking discounts, and in other cases it may be allowed.
A simplistic approach could be to set priorities to discounts, so that the higher priority discount is more likely to get applied. A smarter approach could be to out which available discounts would cause the greatest savings. This could get complicated when there are multiple discounts to potentially apply to multiple order items.
The order of stacking discounts will affect prices also.

Related: e-commerce-algorithm-for-calculating-discounts

Safe guards should also be put in place to prevent negative sales. We may also want to prevent or warn against allowing discounts that will end up making order items sell for free.

Convert OrderCoupon to a multi-code discount constraint

Rather than creating many OrderCoupons (discounts) with unique codes, it would be easier to create one discount and specify many codes. Each code might need to be given a use limit, or perhaps single use vs unlimited.

Order creates an outstanding amount when using single use discount

Silvershop Discounts dev-master
SS version 3.3

  1. Create a few single use Coupons, which use a percentage (eg 99%) and apply to the whole order.
  2. Open an incognito window
  3. Make an order and apply a single use discount. This order will go through fine
  4. In the same session, create a new order, using a new single use coupon. The order will appear to not apply the discount and have the full amount as the remaining to pay. The correct discounted amount goes through to the payment gateway (eg DPS) but the order does not get marked as Paid.

I've run into this issue consistently across SilverStripe, SilverShop and Discount versions. It has been notoriously hard to replicate, but the above should work.

screen shot 2017-04-20 at 4 27 30 pm

removediscount bug in DiscountedOrderExtension

public function removeDiscounts()
    {
        foreach ($this->owner->Items() as $item) {
            $item->Discounts()->removeAll();
        }
    }

should be changed to

    public function removeDiscounts()
    {
        foreach ($this->owner->Items() as $item) {
            $item->Discounts()->removeAll();
        }

      
        foreach ($this->owner->Modifiers() as $modifier) {
            if ($modifier instanceof OrderDiscountModifier) {
               $modifier->Discounts()->removeAll();
            }
        }
      
    }

Free / discounted shipping coupon

Discounting shipping, or making it free via a voucher is desirable.

This could be implemented either as a subclass of OrderCoupon, or as an option on OrderCoupon.

To consider:

  • Could free shipping only apply to a particular product?
  • Replace shipping with a special 'free shipping' type, or simply apply a reduction?

[Notice] Undefined property: OrderDiscountModifier::$Amount when adding to cart

I am using "silvershop/core": "1.3.0" and "silvershop/discounts": "1.2.0", old I know but it works for my client.

I just upgraded the server from PHP 7.0 to 7.1 and now it shows this error when I try and add a product to the cart. See the full error below. Any ideas what might be gong on. If i switch back to 7.0 the site runs fine.

[Notice] Undefined property: OrderDiscountModifier::$Amount
GET /products/locks-and-latches/over-centre-catches/adjustable-stainless-steel/ojop-701s-ass-ss-over-centre-catch-non-locking/
Line 3048 in C:\Nimbler\ovesco\framework\model\DataObject.php

Source
3039 $val = get_class($this);
3040 return DBField::create_field('Varchar', $val, $fieldName);
3041
3042 } else if(array_key_exists($fieldName, self::$fixed_fields)) {
3043 return DBField::create_field(self::$fixed_fields[$fieldName], $this->$fieldName, $fieldName);
3044
3045 // General casting information for items in $db
3046 } else if($helper = $this->db($fieldName)) {
3047 $obj = SS_Object::create_from_string($helper, $fieldName);
3048 $obj->setValue($this->$fieldName, $this->record, false);
3049 return $obj;
3050
3051 // Special case for has_one relationships
3052 } else if(preg_match('/ID$/', $fieldName) && $this->hasOneComponent(substr($fieldName,0,-2))) {
3053 $val = $this->$fieldName;
3054 return DBField::create_field('ForeignKey', $val, $fieldName, $this);
Trace
DataObject->dbObject(Amount)
DataObject.php:2681
DataObject->setField(Amount,0)
OrderDiscountModifier.php:50
OrderDiscountModifier->getDiscount()
OrderDiscountModifier.php:82
OrderDiscountModifier->getAmount()
ViewableData.php:120
ViewableData->__get(Amount)
DataObject.php:3048
DataObject->dbObject(Amount)
DataObject.php:2681
DataObject->setField(Amount,0)
OrderDiscountModifier.php:50
OrderDiscountModifier->getDiscount()
OrderDiscountModifier.php:27
OrderDiscountModifier->value(30)
OrderModifier.php:77
OrderModifier->modify(30)
OrderTotalCalculator.php:33
OrderTotalCalculator->calculate()

Fix documentation around Discount vs Specific Price

The difference is confusing and not immediately clear. The normal user expectation seems to be that Discount will update the displayed price of the product. I think we should do two things:

  1. In the short term update the documentation to spell out what each does.
  2. In the longer term update the logic so Discounts affect the displayed price as well. That could be an option when the discount is created to maintain backwards compatibility.

Here's a sample explanation for the docs (taken from a recent gitter conversation): If you create a "Discount" from the Discounts tab in the CMS that is actually not applied until checkout. It becomes a line item in the order, just like if the customer typed in a coupon code but with the code. To discount the pricing for a specific product you would go in and edit that product and there is another set of discount controls in the Pricing tab on the product.

Discount (coupon) shows in modifiers even without using it

I setup coupon. Then in the form I did not enter the code so its only natural that I wont get any discount. After submission of form I receive notification email with correct total and no discount. However when I login in the admin to view the order, the discount is showing up in the modifiers.

Individual Item Value Discounts are not displaying in the templates

Eg: I created a a 40% discount for some individual items. Throughout the front-end (product listings / product details) It still displays the non-discounted price ... $40 not $20 ... When we talked last, I thought $Price 'should' display the discounted price? The only time I'm seeing any discounts is during the summary checkout step table?

Create action model

One Discount should be able to have many actions. This way we can start working towards complicated actions like "discount cart and shipping", or "get x free".

This module relies on class `ShippingFrameworkModifier` existing

If I install the discount module on a base shop install I get the following notice:

Modifier class "ShippingFrameworkModifier" does not exist.

I've tracked this down to Shop\Discount\Calculator line 92:

if($shipping = $this->order->getModifier("ShippingFrameworkModifier")){

In Order::getModifier there's a ClassInfo::exists check that's throwing the user_error because that class doesn't exist.

Either there's a dependency on silverstripe-shop-shipping or a better way of determining if the order has that modifier without needing the class to exist.

DistanceShippingModifier is not working out distances correctly?

  1. Created a warehouse at 616 Manukau Rd, Epsom, Auckland 1023
  2. Created a DistanceShippingModifier with the following 'Fares'
    0 - 100 = $50
    100 - 200 = $80
    200 - 4000 = $110
  3. Entered 610 Manukau Rd, Epsom, Auckland 1023 as my Shipping address
  4. Shipping costs say $110 (It should be $50)?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.