Adding taxes - paypal variables - javascript

I'm trying to add taxes to my paypal settings for my shopping cart.
Here's what I got in the Javascript code:
//static paypal request arguments
var pp_settings = {
cmd: '_cart',
upload: 1,
no_note: 0,
bn: 'JQPayPalShop_ShoppingCart_EC_US',
rm: 2,
custom: '',
discount_rate_cart:50,
tax_rate:9
};
I added "discount_rate_cart" to test if I was adding the variables at the right place, and yes the total is 50% cheaper. So I'm at the right place.
But then, when adding "tax_rate", I can type whatever I want next to it, it's just not working. No taxes added on the checkout page.
Any idea why?
EDIT: For those who wants to see the full code : http://jsfiddle.net/uNV6f/

You have the wrong variable name. For individual items, it's ok, but it looks like you're trying to set it up for the whole cart.
In that case it should be tax_cart
Check out this document with the full list of variables that you can use:
https://cms.paypal.com/us/cgi-bin/?cmd=_render-content&content_ID=developer/e_howto_html_Appx_websitestandard_htmlvariables#id08A6HH0D0TA

Related

Programmatically add products to a cart – Odoo 13

I have a custom module that creates a form. Based on the answers inside this form I’m generating order line. After user sends this form I’m creating sale order with all products from the generated order line.
So from JavaScript I’m sending an JSON with products to buy:
order_data = [{product_id: 1, amount: 10, …},{product_id: 2, …}, …];
note = '';
this._rpc({
route: '/api/create_order',
params: { order_products: order_data, note: note }
}).then((data) => {
window.location = '/contactus-thank-you';
}).catch((error) => {
console.error(error);
});
And then inside Python I’m creating sale order based on the JSON:
#http.route('/api/create_order', type='json', auth='user', website=True)
def create_order(self, **kw):
uid = http.request.env.context.get('uid')
partner_id = http.request.env['res.users'].search([('id','=',uid)]).partner_id.id
order_products = kw.get('order_products', [])
note = kw.get('note', '')
order_line = []
for product in order_products:
amount = 0
if 'custom_amount' in product:
amount = product['custom_amount']
else:
amount = product['amount']
if amount > 0:
order_line.append(
(0, 0, {
'product_id': product['product_id'],
'product_uom_qty': amount,
}))
order_data = {
'name': http.request.env['ir.sequence'].with_user(SUPERUSER_ID).next_by_code('sale.order') or _('New'),
'partner_id': partner_id,
'order_line': order_line,
'note': note,
}
result_insert_record = http.request.env['sale.order'].with_user(SUPERUSER_ID).create(order_data)
return result_insert_record.id
But instead of generating sale order directly I need to use workflow from Odoo’s eCommerce addon. That way user can for example edit delivery address, choose payment etc. So I think I just need to programmatically put all the product inside a cart and then rest will be taken care of by Odoo built-in functionality.
But how? I’ve tried to find something inside Odoo source code but it is quite hard to grasp anything.
Odoo uses a typical Sale Order for handling products inside a cart. But the process isn't as simple as just creating Sale Order with some products. Odoo needs to know which order is linked with which cart etc.
Luckily Odoo has a method for dealing with it. There is a sale_get_order() method that lets you get an order that is currently linked with a cart or create new one if there isn't any.
I'm not sure if it is documented anywhere outside the source code so here is a slice from the code (/addons/website_sale/models/website.py):
def sale_get_order(self, force_create=False, code=None, update_pricelist=False, force_pricelist=False):
""" Return the current sales order after mofications specified by params.
:param bool force_create: Create sales order if not already existing
:param str code: Code to force a pricelist (promo code)
If empty, it's a special case to reset the pricelist with the first available else the default.
:param bool update_pricelist: Force to recompute all the lines from sales order to adapt the price with the current pricelist.
:param int force_pricelist: pricelist_id - if set, we change the pricelist with this one
:returns: browse record for the current sales order
"""
# ...
I'm using it alongside another method _cart_update() that lets me easily update products inside this order. There is also sale_reset() and I'm using it just to be sure that current session will be updated with particular sale order every time.
sale_order = request.website.sale_get_order(force_create=True)
request.website.sale_reset()
sale_order.write({'order_line':[(5, 0, 0)]})
for product in order_products:
sale_order._cart_update(product_id=product['product_id'], line_id=None, add_qty=None, set_qty=product['amount'])

Django: populate the field based on previous field value - missing the last step to make it work

Like many, I want to populate a field in a django form based on what is selected in another field. I've read alot of answers with javascript(I struggle in javscript, so that's where I'm having trouble with the exemples), and I almost got it working, but the last step(updating the field itself) isn't working so I'd love some help with that part.
Here are the 2 fields. The first fieldthat gets populated from a query and is located in a div named #merch in the form
merchandise = forms.ModelChoiceField(label='Merchandise', queryset=Merchandise.objects.all(),
merch_price = forms.DecimalField(label='Price', min_value=0, max_value=800,
initial='0.00',decimal_places = 2, max_digits=10)
Upon selection, the second field(div named #price) should then display the price based on the merchandise selected. I created the view for the ajax request:
def check_item_price(request):
if request.method == "GET":
item = request.GET.get('item', '0')#the zero as default doesn't seem to work. To verify
price = Merchandise.objects.get(id = item)
return JsonResponse(price.item_price, safe=False)#is it safe to turn safe off?
and the url
url(r'^_item_price', views.check_item_price, name='_item_price' )
Calling the url manually works great, it returns the price in json format
And here is the javascript that is in the html form. The first part works, upon change it calls the url and a json object is returned, but the second part that should update the second field isn't working. I admit my lack of knowledge in javascript is probably at fault here. I tried many variations based on examples, none worked for me.
<script type="text/javascript">
jQuery(document).ready(function() {
$('#merch').change(function() {
var item = $(this).find(':selected').val();
$.getJSON('/classes/_item_price/',{item:item},
function(data) {
$('#price').append("<option value=" + data.value + "></option>");
});
});
});
</script>
Any pointers on what to fix in the javascript?
Thanks!
After letting it marinate in my head for 2 months, I went back to it and finally made it work. Here is the right code
jQuery(document).ready(function() {
$('#merch').change(function() {
var item = $(this).find(':selected').val();
$.getJSON('/classes/_item_price/',{item:item},
function(data) {
document.getElementById('id_merch_price').value=data;
});
});
});
</script>
First, the ID wasn't precise enough, but also the way of updating it wasn't the right one it seems. I truly feel lost anytime I have to do research on javascript or jquery. So may ways to do the same thing, it's almost impossible to learn for a casual coder like me.

pug- do an action based on if an element exits in a variable

I am using Express js to build a web app. I use an API to get some data and then send it to a pug file in the below format.
res.render('native.pug', {product_name: body.products, cart_items:body.cart, item_count:body.count, amount: body.totalAmount, sid: sess.id});
body is a json object.
I get id field(along with other fields) in both body.products and body.cart
body.products consists a list of all the products and their details
body.cart consists of details of all the products the user added to the cart.
Now, in the native.pug file, I wish to display different texts, based on if a particular id from body.products is present or not in body.cart
Here is what I tried
each prod in product_name
if prod.id in cart_items.id
button Add to Cart
else
button abc
I get the following error
Add to Cart 23| else 24| button abc Cannot use 'in' operator to search for '590' in undefined
Where am I going wrong exactly?
EDIT: indentation
You probably want something like this:
if (cart_items.indexOf(prod.id) > -1)
button Add to Cart
else
button abc
This assumes that
prod is an object with an id property
cart_items is an array of ids

How to push a second product into the data layer with GTM

I'm patching enhanced eccommerce reoprting code for Google analytics using Google Tag Manager - by screen scraping data for a checkout step in the process. The code look like this:
var els = document.querySelectorAll('div.field_cart');
Array.prototype.forEach.call(els,function(element){
dataLayer.push({
'event': 'checkout',
'ecommerce': {
'checkout': {
'actionField': {'step': 1, 'option': 'Visa'},
'products': [{
'id': $('div.field_cart')[0].innerText,
'price': $('div.field_cart')[1].innerText.match(/[0-9]+/),
'quantity': $('div.field_cart')[2].innerText
}//,{}...//
]
}
});
})
the problem is that if there are is more than one item - the second ovewrites the first etc instead of getting pushed ... I'd like to know how to append a new product to the products object?
Because you can't push the product alone you need to build object that has all the products inside.
first step is to retrieve object that is already in dataLayer (even if empty)
get the products object
push new item inside
push the whole object to dataLayer
If you have troubles with any of this steps let me know.
Try to define dataLayer varible first with:
var dataLayer = window.dataLayer || [];
It will take existing dataLayer variable and add use it or if there is none it will make array for it.
Also, I can see that you are using lower case "datalayer". It should be "dataLayer".
I hope this will help.
I turns out google tag manager rewired dataLayer.push() method to fire events and guard the dataLayer's size. A side effect is that it does not operate as expected. The way to overcome this issue was to push all the scraped product data into a javascript variable and once it was ready, to push that variable into the dataLayer as follows:
function scrape2DL() {
dataLayer.push({'ecommerce.checkout.actionField': {step: 2}}); //action object
var base = 0;
var products=[];
while (base < $('div.field_cart').length/4) {
products.push([{id: $('div.field_cart')[4 * base + 0].innerText, price: $('div.field_cart')[4 * base + 1].innerText.match(/[0-9]+/), quantity: $('div.field_cart')[4 * base + 2].innerText}]);
base += 1;
}//while
dataLayer.push({'ecommerce.checkout.products': products}); // add a product
}
scrape2DL();
dataLayer.push({event: 'checkout'}); // for GTM triggers
However it turns out that it is possible to fetch the products from the datalayer into a javascript variable using the datalayer get method and subsequently append more products into it.
However I ultimately avoided this aproach as it skips the event and size guard check wired into dataLayer.push().
The folowing resources were of some help:
SO question titled Console returns value but Google Tag Manager variable does not
Google Tag Manager For Nerds by Simo Ahava.

How to load related entity of external data source in Lightswitch (Visual Studio 2013)

I have 2 tables which are both in an Azure SQL Database which is connected to my Lightswitch Sharepoint app. I am doing some manipulation of the data in code, and it appears to be working, except that when I load the entities from one table, I am not able to see the related entities in the other.
Basically, I have a products table and an invoice lines table. Each invoice line record contains a product code, which relates to the products table PK. I have defined the relationship in Lightswitch, but when I load the invoice line record, I can't see the product information.
My code is as follows:
// Select invoice and get products
myapp.AddEditServiceRecord.InvoicesByCustomer_ItemTap_execute = function (screen) {
screen.ServiceRecord.InvoiceNumber = screen.InvoicesByCustomer.selectedItem.INVO_NO;
// Delete existing lines (if any)
screen.ServiceDetails.data.forEach(function (line) {
line.deleteEntity();
});
// Add products for selected invoice
screen.getInvoiceLinesByNumber().then(function (invLines) {
invLines.data.forEach(function (invLine) {
invLine.getProduct().then(function (invProduct) {
var newLine = new myapp.ServiceDetail();
newLine.ServiceRecord = screen.ServiceRecord;
newLine.ProductCode = invLine.ProductCode;
newLine.ProductDescription = invProduct.Description;
newLine.CasesOrdered = invLine.Cases;
});
});
});
};
The idea is that a list of invoices are on the screen 'InvoicesByCustomer', and the user clicks one to add the details of that invoice to the 'ServiceRecord' table. If I comment out the newLine.ProductDescription = invProduct.Description line it works perfectly in adding the correct product codes and cases values. I have also tried a few other combinations of the below code, but in each case the related product entity appears as undefined in the Javascript debugger.
EDIT: I also read this article on including related data (http://blogs.msdn.com/b/bethmassi/archive/2012/05/29/lightswitch-tips-amp-tricks-on-query-performance.aspx) and noticed the section on 'Static Spans'. I checked and this was set to 'Auto (Excluded)' so I changed it to 'Included', but unfortunately this made no difference. I'm still getting the invProduct is undefined message. I also tried simply invLine.Product.Description but it gives the same error.
The solution in this case was a simple one. My data was wrong, and therefore Lightswitch was doing it's job correctly!
In my Invoices table, the product code was something like 'A123' whereas in my Products table, the product code was 'A123 ' (padded with spaces on the right). When doing SQL queries against the data, it was able to match the records but Lightswitch (correctly) saw the 2 fields as different and so could not relate them.
I may have wasted several hours on this, but it's not wasted when something has been learnt...or so I'll tell myself!

Categories

Resources