Cart discount on Virto Commerce Marketing Module - virtocommerce

I would like to do a promotion in Virto Commerce on the cart. In my example i would like to discount the cart with 200 SEK if the customer buys for at least 800 SEK, the VAT/GST in my example is 25%.
This is the effect I'm looking for:
Cart
subTotal: 640
subTotalWithTax: 800
discountAmount: 160
discountTotalWithTax: 200
total: 480
totalWithTax: 600
As far as i can tell the Marketing Module only supports promotions where the discount is applied before taxes. Se comment in storefront code:
ShoppingCart.cs#L390
foreach (var reward in cartRewards)
{
//When a discount is applied to the cart subtotal, the tax calculation has already been applied, and is reflected in the tax subtotal.
//Therefore, a discount applying to the cart subtotal will occur after tax.
//For instance, if the cart subtotal is $100, and $15 is the tax subtotal, a cart - wide discount of 10 % will yield a total of $105($100 subtotal – $10 discount + $15 tax on the original $100).
if (reward.IsValid)
{
var discount = reward.ToDiscountModel(ExtendedPriceTotal);
Discounts.Add(discount);
DiscountAmount = discount.Amount;
}
}
I guess this is a common practice in some markets. But as this is for a B2C solution in Sweden. An advertised discount of 200 SEK on a 800 SEK cart should render a customer facing total price of 600 SEK including taxes.
This is an img of my promotion in the Marketing Module
This gives me the following on the Cart JSON
Cart
subTotal: 640
subTotalWithTax: 800
discountAmount: 160
discountTotal: 160
discountTotalWithTax: 160
subTotalDiscount: 0
subTotalDiscountWithTax:0
discountTotalWithTax: 160
taxTotal: 160
total: 640
totalWithTax: 800 (Calculated. Not in standard JSON response)
So either I've miss configured the promotion or my implementation of the storefront code for promotions is lacking in some way.

Currently, VC implement only the one discount to the order subtotal policy:
When a discount is applied to the cart subtotal, the tax calculation
has already been applied, and is reflected in the tax subtotal.
Therefore, a discount applying to the cart subtotal will occur after
tax. For instance, if the cart subtotal is $100, and $15 is the tax
subtotal, a cart-wide discount of 10% will yield a total of $105 ($100
subtotal – $10 discount + $15 tax on the original $100).
But we are working on change the totals calculation to make this process more flexible and extensible for supporting any calculation policies.
You can achieve what you want by a little customization within your extension module:
Extend ShopingCart class with following code
public class ShopingCart2: ShoppingCart
{
public decimal DiscountAmountWithTax
{
get
{
return DiscountAmount + DiscountAmount * TaxPercentRate;
}
}
public override decimal TaxTotal
{
get
{
var result = base.TaxTotal;
result -= DiscountAmountWithTax - DiscountAmount;
return result;
}
}
public override decimal DiscountTotalWithTax
{
get
{
var result = base.DiscountTotalWithTax;
result += DiscountAmountWithTax - DiscountAmount;
return result;
}
}
}
Extend domain CustomerOrder type with the same code as for ShoppingCart above
Register your ShoopingCart2 and CustomerOrder2 in AbstractTypeFactory
AbstractTypeFactory<ShoppingCart>.OverrideType<ShoppingCart, ShoppingCart2>();
AbstractTypeFactory<CustomerOrder>.OverrideType<CustomerOrder, CustomerOrder2>();
Update your storefront to latest version from dev (this commit required for normal work https://github.com/VirtoCommerce/vc-storefront/commit/2464548c171c811a9d63edba0bdf6af93e8c902b)
Modify ShopingCart class in your storefront - add same changes as you made in your new ShoppingCart2 type earlier.
Get the desired behavior

Related

solidity reverse auction logic?

I am writing reverse auction with solidity and somewhat logic is confusing.
In regular auction, Seller make an auction with item, buyer (msg.sender) bids on the item, that bid amount will transfer to the smart contract, when auction is end, winning bid goes to the seller and other non-winning bid get refunded to the non-winners' account.
In reverse auction, Buyer create the auction, potential seller offer(bid) the price, lowest bid amount get selected and buyer (auction creator) will transfer money to the final offerer (bid winner with lowest price offer).
what i thought was that simply change the initial buyer and seller compare to the regular auction but it does not work
if (msg.value > winningBid) {
pendingReturns[msg.sender] += msg.value;
auctionWinner = msg.sender;
winningBid = msg.value;
emit RegularBidding(msg.sender, msg.value);
}
is the regular auction bidding logic (which works fine)
if (msg.value < winningBid) { // since winner is the one who offers the lowest price
pendingReturns[product.buyer] += msg.value; // when offer is made, buyer send money to the smart contract and get refunded later except for the winning offer amount
auctionWinner = msg.sender; // auctionWinner is the offerer (I think this line is wrong)
winningBid = msg.value;
emit ReverseBidding(product.buyer, msg.value); // buyer transfer the value to the seller
}
I know this code is wrong and logic is a bit confusing to me since msg.sender is totally opposite and buyer has to deposit money to the smart contract and get refunded later.

Reduce product price from php script

I am trying to make a php script that reduces the base price of a product by 20 but it instead changes the base price with the discounted price. I can't figure out what is wrong with the code.
$product_baseprice = round(1.19*($product->base_price));
$product->base_price = $product_baseprice - 20;
$product->update();
There's no "base_price" property in the Product class object.
The base price must be updated with the $product->price property.
Or, like suggested, you can create a new SpecificPrice() where you can apply a percentage-based discount on the product.
Solved it
$pret = $product->base_price;
$pret_redus = $pret - 16.81;
$product->price = $pret_redus;
$product->update();

Odoo v10 display amount in company currency in purchase tree and form view

I am using Odoo v10 .
As we know in purchase.order, there is a base (Monetary) field amount_total which contains value of total amount of a Purchase Order based on (self) currency_id .
Now, I create a new float field home_currency_amount_total in purchase.order .
home_currency_amount_total = fields.Float(string='Total Amount in company currency', store=True)
How can i have a value in this field based on company currency? i.e. I want to have a corresponding value in company base currency and can be used in my tree & form views.
I am new to Odoo and I wonder if there is a "shortcut" (e.g. a built-in compute method) instead of I have to write up related codes.
There is a built-in method for conversion of currency.
Eg.
#api.model
def _compute(self, from_currency, to_currency, from_amount, round=True):
if (to_currency == from_currency):
amount = to_currency.round(from_amount) if round else from_amount
else:
rate = self._get_conversion_rate(from_currency, to_currency)
amount = to_currency.round(from_amount * rate) if round else from_amount * rate
return amount
So, if you want to calculate the conversion you can use this method.
This method takes 3 arguments, first from currency, second to currency and amount which you want to convert as a third argument.
Eg.
self.env['res.currency']._compute(order.currency_id,order.company_id.currency_id,order.amount_total)
Update :
Create you field like this.
home_currency_amount_total = fields.Float(string='Total Amount in company currency', compute="_compute", store=True)
#api.depends('order_lines.price_subtotal','company_id','currency_id')
def _compute(self);
for order in self:
home_currency_amount_total = self.env['res.currency']._compute(order.currency_id,order.company_id.currency_id,order.amount_total)
You can do it using following method.
class PurchaseOrder(models.Model):
_inherit = "purchase.order"
#api.multi
#api.depends('amount_total')
def get_amount_in_company_currency(self):
for purchase_order in self:
if purchase_order.currency_id.id!=purchase_order.company_id.currency_id.id:
currency_id = purchase_order.currency_id.with_context(date=purchase_order.date_order)
purchase_order.home_currency_amount_total = currency_id.compute(purchase_order.amount_total, purchase_order.company_id.currency_id)
else:
purchase_order.home_currency_amount_total=purchase_order.amount_total
home_currency_amount_total = fields.Float(string='Total Amount in company currency',compute="get_amount_in_company_currency",store=True)
In above code we have create one compute field store True, it means value will be store in the database.
When amount_total will change at that time system will calculate home currency amount.
In method we have checked if company currency & purchase order currency is different then system will compute currency amount.
In odoo base module on method is available for compute currency, in which you can pass date in the context.
purchase_order.currency_id.with_context(date=purchase_order.date_order)
Based on context date system will take currency rate, if you not pass
any date then system will take current date rate.
This will help you.

Adding percentage to a value using a helper?

I have the following existing helper in my Invoice model of my Rails application:
def total_price
line_items.to_a.sum(&:full_price)
end
What I would like to do is have an additional helper called total_vat which adds 20% to the total_price helper. Is this possible?
I will eventually be adding a third helper which calculates the difference so I can print just the amount of VAT due.
Creating multiple helpers is absolutely possible.
def vat
total_price * 0.2
end
def total_price_including_vat
total_price + vat
end

Adding product to shopping cart via Magento API results in a 0 price

I'm trying to programmatically create an order and invoice in Magento but whenever I add products to the shopping cart, the price of each product is set to 0, thus resulting in a NULL total.
I also tried the moveToCustomerQuote method but that throws a Magento Fault saying that the customer quote (shoppingcart ID) doesn't exist.
Here's my code
$cart = $magi->execute("cart.create");
$add_customer = $magi->execute("cart_customer.set",array($cart,$customer));
$products = array(array(
"product_id" => 167,
"qty" => 50
));
$add_product = $magi->execute("cart_product.add",array($cart,$products));
Is there something I'm doing wrong or is there another step I should take to get the product to list the price properly?