Developer forum

Forum » Development » Adding discount programmatically

Adding discount programmatically

Dmitrij Jazel
Reply
Hello DW guys,

Question for you here, I have a web-shop that uses standard discounts.
But the way how they are supposed to be added is not really decided yet. The user has no possibility to add discount via admin panel, so I am making a custom solution for that. Please correct me if I am wrong here...

My current thoughts to fix this are:
1) To extend Sales discount provider.
In this case maybe I could use some hints and examples if possible, Since I just want to add a standard fixed amount or percentage discount for the solution (not some custom way to count it). I am using service to receive data regarding the sales and discounts, so generally speaking the task is simply to push it further through.

2) Since I am using, services to receive discount information, I could add it directly to the database... I found a table called EcomSalesDiscount that contains information regarding my discount. But how it defines what Products and product-groups you are adding the discount to? I am sure there must be some more tables that I would have to add some kind of information if I making a discount in this way. Anything I should be aware of here?

Some tips and suggestions on how to solve this task in the best way would be more than appreciated!

Kind regards,
Dmitrij


Replies

 
Vladimir
Reply
Hi Dmitrij!
why user can't add discounts via admin panel(Management center/eCommerce/Product Catalog/Sales discount)?

1) there is an example in documentation
http://developer.dynamicweb-cms.com/api/ecommerce/Dynamicweb~Dynamicweb.eCommerce.Orders.SalesDiscounts.SalesDiscountProvider.html

2) Products and product-groups are stored in [SalesDiscountParameters] field.. among with other discount parameters

Regards,
Vladimir

 
Imar Spaanjaars Dynamicweb Employee
Imar Spaanjaars
Reply
Hi Dmitrij,

As Vladimir pointed out, you can indeed add discounts using the Management Center. If the supported discount types are sufficient for you (there are many different types), that's certainly the recommended way to do it.

However, if you have the need to get discount values from a service at run-time, take a look here:
http://devierkoeden.com/articles/implementing-a-salesdiscountprovider.aspx

The article shows you how to implement an IP based discount where you a discount based on your IP address. Just an example, but it shows the underlying principles.

Cheers,

Imar
 
Dmitrij Jazel
Reply
Hello guys,
Well, the users cannot use dynamicweb backend because they are going to control the shop remotely.
What I need is to be able to add a discount to user groups from service. That discount must be saved in the system and eventually be used from there on, applied when needed as normally made discounts do. As I understand I would just need to add new discount in the DW db table EcomSalesDiscount.
Only thing is that when I make new discount at the backend, I provide a specific product I want to add a discount to, eventually in EcomSalesDiscount I can see the discount I made, UserGroup I added, but no product or productGroup it links to.
Or maybe there is a easyer way to do it?
Some guidelines, or suggestions would be much appreciated on this one :-)

Kind regards,
Dmitrij

 
Dmitrij Jazel
Reply
Hello again guys,
Sorry for such a late reply. But I think I really need find a best answer for this one.
I can feel I might be missing really easy way to solve this one. If I choose just talk directly to the EcomSalesDiscount table

I found out that in order to make Sales Discount I can simply create it in the Database, but I do not like this approach.

This is an example of what kind of discount I need to add:
Since, the website has many userGroups, and each group (Group Alpha for example) can have a fixed percentage discount like -20% for bananasGroup fron 1st of may to 20th of jully.
The same Alpha group can have another discount with another percentage for another ProductGroup (Tomatoes for example) for different period. But again (percentage, like -30% off).
Than another group UserGroup (Beta group) must have their discount of their own for the same bananasGroup group for example or any other ProductGroup.

Options so far:
1) If I override the discount provider, I would really appreciate some guidelines or maybe a little hint example of what and how basically.
Cause that discount provider adds a discount to the order. If user meets specific criteria. But the discount is added generally when creating the order. And is very generic. I would need to go through the list of orderliens and check if the productGroup is under the discount for the user. So I am not sure how can I use it. In addition to that, the discount must be shown while viewing the products in the product catalog.

So the way how DW handles discount is ok, What I would need here, is to add a discount to the DB for example, and through that allow DW manage the discount as normally made discount and that would be what I would like.



2) So option nr2, is adding discount as such to the system.
I could try to add the discount directly through the database. But I am not sure about this thing here.
When I am making a new discount system adds new entry in EcomSalesDiscount table. There it is pretty much streight forward, except for ProductGroup that gets the discount. Column SalesDiscountParameters gets the productGroup, And I do not know how can I correctly add ProductGroup to the discount.

I would imagine that it should be possible to make a new discount object. Than add a discount ProductGroup or remove it. Add UserGroup to the discount object or remove it etc... and than simply save that object so it could be called again.

Is it possible at all in DW? 

Could you guys please help me with this one? 
Some suggestions or guidelines would be more than appreciated!

Kind regards,
Dmitrij
 
Vladimir
Reply
Hej Dmitrij,
I vvery want to help you ...

For your example, it is possible to use standard ProductDiscount. If the gui is not suitable for a creating discount, you can add a  row in table EcomSalesDiscount, then, for your example, it is necessary to create three rows, for example with the following parameters:
SalesDiscountID - useNumberGenerator.GetNumber ("SALESDISCNT") to get new id
SalesDiscountDiscountType = Dynamicweb.eCommerce.Orders.SalesDiscounts.ProductDiscount
SalesDiscountCustomersAndGroups = GRP_465, GRP_441
SalesDiscountValueType = Percentage
SalesDiscountValuePercentage = 20
SalesDiscountActive = 1
SalesDiscountParameters =   - where [g : GROUP1]  - product group,  [p: PROD5690,] - product ( or [p: PROD5690,VAR1]

Exemple how to create a new discount provider:
Imports Dynamicweb.eCommerce
Imports Dynamicweb.eCommerce.Prices
Imports Dynamicweb.eCommerce.Orders
Imports Dynamicweb.eCommerce.Products
Imports Dynamicweb.Extensibility
Imports Dynamicweb.eCommerce.Orders.SalesDiscounts

    < _
    AddInName("My discount"), _
    AddInDescription("Your description"), _
    AddInActive(True)
    > _
    Public Class MyDiscount
        Inherits SalesDiscountProvider

        Private _ProductsAndGroups As New ProductsAndGroupsHandler()

        <AddInParameter("Products"), AddInParameterEditor(GetType(Editors.ProductsAndGroupsEditor), "width=300px;height=100px")> _
        Public Property ProductsAndGroups() As String
            Get
                If _ProductsAndGroups Is Nothing Then
                    _ProductsAndGroups = New ProductsAndGroupsHandler()
                End If
                Return _ProductsAndGroups.ToString()
            End Get
            Set(ByVal value As String)
                If _ProductsAndGroups Is Nothing Then
                    _ProductsAndGroups = New ProductsAndGroupsHandler()
                End If
                _ProductsAndGroups.ParseData(value)
            End Set
        End Property


        Public Overrides Sub ProcessOrder(ByVal _order As Order)
            For Each line As OrderLine In _order.OrderLines
		If Base.ChkNumber(line.Type) <= 0 AndAlso _ProductsAndGroups.IsProductIncluded(line.Product) AndAlso line.Quantity >= Me.ProductQuantity Then
                Select Case DiscountValue.Type
                    Case DiscountTypes.FixedAmount
                        Dim line As OrderLine
                        line = Me.CreateAmountOrderline(_order, DiscountValue.Amount, False)
                        _order.OrderLines.Add(line, False)
                    Case DiscountTypes.Percent
			Dim discount As Double = CalculateDiscountPrice(line, DiscountValue.Amount)
			Dim newLine As OrderLine = CreateOrderLine(_order, discount)
			_order.OrderLines.Add(newLine, False)
		    End Select

		End If
            Next
        End Sub

	Private Function CalculateDiscountPrice(ByVal _orderLine As OrderLine, ByVal _discountPercent As Double) As Double
		Dim discountPrice As Double = 0

		If _orderLine.Type <> Base.ChkString(Base.ChkInteger(OrderLine.OrderLineType.Discount)) Then
		    discountPrice += _orderLine.UnitPrice.PriceWithoutVAT / 100 * _discountPercent * _orderLine.Quantity
		End If

		Return discountPrice * -1
	End Function

	Private Function CreateOrderLine(ByVal _order As Order, ByVal discountPrice As Double) As OrderLine
		Dim line As OrderLine = New OrderLine()
		line.Order = _order
		line.Quantity = 1
		line.ProductName = DiscountName
        line.SetUnitPrice(discountPrice)
        line.DiscountID = DiscountID

        line.Type = Base.ChkString(Base.ChkNumber(OrderLine.OrderLineType.ProductDiscount))

		Return line
	End Function

    End Class
Best regards,
Vladimir




 
Dmitrij Jazel
Reply
Hi Vladimir,


Allright, well I will try to clear out this one here
as I checked your, and Imars code. And I have some questions...

For example, Imar calculates Discount percentage depending on the IP.
But how he defines what exact % off it is. I am not sure about that. He also set's up the discount in the backend discount.
And I would love to add discount myself. But that is not one time discount I would have to add and than reference to it. There could be hundred of thousands discount variations if not milions.

What I need is:
1) Add multiple custom discounts to the database directly, or via API, so that when the user visits the product catalog, the whole thing should already be ready to go. So there would be no need in implementing any kind of "providers" to achieve this.

2) if 1st is not the option, than I would like to add a discount provider (SalesDiscountProvider or any other provider if necessary).
So that it could change the price during the runtime, and use this price calculation method every time the product is viewed or requested. (viewed in product catalog and orderlines) with that modified price.

I personally would love to use option #2, if this price calculation method would not put too much load for calculating every single product price instance it encounters. All the time, for All the users currently checking the solution. But I guess to solve this one all I need is correctly implement it.

The thing is that all the data about the discounts is imported from another server. Than I have all this data, that has no relation to the Dynamicweb discounts.
I would have to do the #1 approach by creating a complicated discount import. That I feel could be quite hard to do.
When instead I could go with option #2 and calculate discounts on the fly, when knowing what username is loggedin, what group it has, what special parameter it contains in business phone number field (discount reference) and - the eventual product I am looking at and special discount reference value of it own.

In your code - I am not sure if you are using one of the discounts you added yourself in the backend already, and than apply it to the price. Or you are making discount in some other way. Cause what I need is to be able to manage alot of discounts at the same time. 

I can see you are getting DiscountValue.Amount, but I am not sure how you get it, or how it is defined (the amount and percentage off or money off).

I hope you understand what I am trying to tell you here? :-)

Kind regards,
Dmitrij

 
Vladimir
Reply
This post has been marked as an answer
Hi Dmitrij!
Looks like I'm begin to understand (I hope so) that you want to achieve ...

1) Imar calculates Discount percentage depending on the IP:
Imar do not calculate - he just checks, is there discount or not
2) The value of discount is stored in inherited property DiscountValue.Amount,
and property DiscountValue.Type used to determine is it % or not
3) DW discounts are not applied when products in the product catalog
- to solve this you may create a product template extender, where you will define % of discount and render it

So I suggest:
1)  Don't add rows in EcomSalesDiscount.
2)  Create a new Table for your discounts, that can store all discount rules from web service
3)  Implement a provider that will used new Table to determine % of discount  and add appropriate row in order

Best regards,
Vladimir

Votes for this answer: 0
 
Imar Spaanjaars Dynamicweb Employee
Imar Spaanjaars
Reply
But that is not one time discount I would have to add and than reference to it. There could be hundred of thousands discount variations if not milions.
If that's the case, a SalesDiscountProvider may not be what you need. It sounds as if you want to create specialized prices for individual users, in which case a PriceProvider would be the way to go.

For more info: http://developer.dynamicweb-cms.com/documentation-8.0/for-developers/%28moved%29-ecommerce/%28moved%29-extensibility/providers/price-providers.aspx

Cheers,

Imar
 
Dmitrij Jazel
Reply
Hej Guys,
First off thanks alot for the help again :-) seriously means alot to me as you would imagine...

Vladimir:
Yes you got it right this time :-)
according to your suggestion I am doing 1 and 2 already... the question would be what provider it must be, I am storing discounts all is fine, all I need is find a way to apply those discounts for the existing product prices...

Imar,
I actually Wanted to suggest myself that if I should use PriceProvider, cause it achieved similar task that I needed.
Question for you Imar would be if I define new PriceRaw for product in PriceProvider, than this price will correspong to Ecom:Product.Price.Price, this price will follow everywhere I ask for it, and if I call for this price in other custom parts it would correspond as default price right? :-)
And if the user does not meet the requirements than FindPrice will return null and default price would be used (default price is a product price stored in products table)?

Thanks alot guys for the help and patience!!!
Regards,
Dmitrij
 
Imar Spaanjaars Dynamicweb Employee
Imar Spaanjaars
Reply
Hi Dmitrij,

Yes, correct. Dynamicweb calls all configured PriceProviders until one returns a price. If all of them return null (for example, because the user is anonymous or doesn't qualify for a special price) Dynamicweb falls back to the default PriceProvider which returns the price configured in the backend.

Hope this helps,

Imar
 
Dmitrij Jazel
Reply
 Hej Guys,

I'v got it working with Imars Price Provider.
Works great! :-)

Only problem there is no way to indicate that the item is under the discount...
Not sure if that is possible with Price Provider.

Thanks alot for help guys!

Kind regards,
Dmitrij
 
Dmitrij Jazel
Reply
Hej Guys,

I have one more question here,
What if the price get's changed (with price provider) is there any way to indicate that in the frontend? Like put a discount sign on it and/or strike out old price?

Any suggestions? :)

Kind regards,
Dmitrij 

 
Vladimir
Reply
 Hi Dmitrij,
what if create custom field for product and assign it to true in 
PriceProvider. Or even create custom field to store base price, 
and then with help of ProductTemplateExtender show new and old price

 Best regards,
Vladimir

 
Dmitrij Jazel
Reply
Hi Vladimir,

Thanks for suggestion,
I will try this one - hope this works :-)
Meanwhile, are there any other suggestions I could try consider?

Kind regards,
Dmitrij
 
Vladimir
Reply

all my other ideas definitely are worse ie not so good :)

Best regards,
Vladimir

 

You must be logged in to post in the forum