To get the weight of product in ebay api - ebay-api

Currenly i am working in ebaysdk. I am facing the problem which is the weight of the product. how can i can get product weight ? I used trading api but most of weight of the products equal to 0. is there any way to get every product weight? I requested like this:
response = api_trading.execute('GetItem' ,
{"ItemID":"184097524395",'DestinationPostalCode':'2940','DestinationCountryCode':'GB'})

Some items have their weight included in the "Items Specifics" section, which can only be extracted by setting "IncludeItemSpecifics" to "true" in the trading api execution:
response = api_trading.execute('GetItem' , {"ItemID":"254350593466", "IncludeItemSpecifics": "true"})
Then, one possible way to get the details of interest is by looping through the dictionary:
for d in response.dict()['Item']['ItemSpecifics']['NameValueList']:
print(d)
The weight Name and Value will be in one of those dictionaries:
...
{'Name': 'Item Length', 'Value': '1', 'Source': 'ItemSpecific'}
{'Name': 'Item Weight', 'Value': '2.25', 'Source': 'ItemSpecific'}
{'Name': 'Item Width', 'Value': '1', 'Source': 'ItemSpecific'}
...
Source:
https://developer.ebay.com/devzone/guides/features-guide/default.html#development/ItemSpecifics.html

It seems like if the seller does not indicate a weight in the first place, the api has nothing to show for it.
If shipping is free, most likely the seller does not bother entering the weight of the item. So perhaps find those products whose shipping is not free, maybe the seller will indicate the weight for shipping calculations.
"ShippingDetails": {"ShippingType": "Calculated"}
I also tried GetItem and it can show weight of the item as long as weight is available. I also tried GetItemShipping and it can show weight of item if available, but needs DestinationPostalCode.
Souce:https://github.com/timotheus/ebaysdk-python/issues/304

Related

How can I get a message from Binance API when my order is filled

I created a limit buy order.
If this buy order is filled so I open the long position, I want to create another order immediately.
So basically, I want to get a message from the Binance server when my order event is filled.
Is there any function to do so?
I am using WebSocket via the python-binance library, so it would be perfect if there is that functionality in the python-binance library.
Thank you.
You can do it by checking the order status. Below code will do the trick.
# Post a new sell order
params = {
'symbol': 'BTCUSDT',
'side': 'SELL',
'type': 'LIMIT',
'timeInForce': 'GTC',
'quantity': 0.001,
'price': sell_price
}
sell_response = spot_client.new_order(**params)
oid = sell_response['orderId']
loop_sell = True
while (loop_sell):
order_check = spot_client.get_order("BTCUSDT", orderId=oid)
order_status = order_check['status']
if order_status == "FILLED":
print("Sell Order Filled")
break
time.sleep(10)
Binance does not currently offer notifications when orders are created, canceled, or fulfilled through API.
You can do it through user streams. Below pointer may help you
https://dev.binance.vision/t/new-order-notification/2261

How to adjust the stock of a product tracked by lots in Odoo via API

OK so I have been banging my head at this problem for way too long by now.
I want to sync stock levels of a product that is tracked with lots between the webshop and Odoo. For this reason I need to be able to make a stock adjustment of a lot via the API (in this case in python).
I have found this possible way of doing it:
odoo(
'stock.move',
'create',
[{
"name": "Webshop stock adjustment",
"company_id": 1,
"location_id": 8, # warehouse
"location_dest_id": 14, # virtual location
"product_id": batch["product_id"][0],
"product_uom": 1,
"lot_ids": [batch["id"]], # I am searching for the id by the lot name beforehand
"product_uom_qty": 1,
"quantity_done": 1,
"state": "done"
}]
)
This, however, results in two moves! One move which has the correct lot, and another one without a specified lot. The latter move is faulty of course, as the product is tracked with lots. This results in a fault lot entry, where I can't change the quantity by hand, as the field is invalid. Worse, it results in wrong stock levels.
You can see the problematic bookings here
I have tried to just create a stock.move.line, like so:
odoo(
'stock.move.line',
'create',
[{
"company_id": 1,
"display_name": "Webshop adjustment", # does not appear
"location_id": location_id,
"location_dest_id": location_dest_id,
"product_id": batch["product_id"][0],
"product_uom_id": 1,
"lot_id": batch["id"],
"product_uom_qty": quantity,
"qty_done": quantity,
"state": "done" # has no effect
}]
)
However that results in a line with no effect: Line
I have also tried to find the stock adjustment wizard, but the only one I found in the code as opposed to the UI, doesn't have a field for lots..
I'd be happy for any input on how to solve this problem!
Meanwhile I managed to solve this problem reliably. I needed to implement a function for that, rather than mucking around with the external API.
The function here is expecting vals with the format below. It reduces whatever batch needs to go first.
[{
'sku': sku,
'qty': quantity
},]
#api.model
def reduce_lots(self, vals):
log(vals)
for product_req in vals:
product = self.env['product.product'].search(
[['default_code','=', product_req['sku']]]
)
if len(product) == 0:
continue
lots = self.env['stock.quant'].search(
['&',('product_id', '=', product[0]['id']),('on_hand', '=', True)],
order='removal_date asc'
)
move = self.env['stock.move'].create({
'name': product_req['order'],
'location_id': 8, # Our Warehouse
'location_dest_id': 14, # Virtual Location, Customer. If you need to increase stock, reverse the two numbers.
'product_id': product.id,
'product_uom': product.uom_id.id,
'product_uom_qty': product_req['qty'],
})
move._action_confirm()
move._action_assign()
product_req['lots'] = []
for line in move.move_line_ids:
line.write({'qty_done': line['product_uom_qty']})
product_req['lots'].append({
'_qty': line['product_uom_qty'],
'_lot_id': line.lot_id.name,
'_best_before': line.lot_id.removal_date
})
move._action_done()
return vals

add an extra column on Tax Report of odoo 10

I need an extra column on odoo tax report. Currently there are two columns Net and Tax. I need to add a column named Gross. This view isn't like other qweb views and not getting it. Screenshot:
The module is account_reports and the file which is generating the report I think is account_generic_tax_report.
It would be great if anyone can suggest me what to do.
Regards.
You can append new column names in the list column_header
in function get_column_names, addons/account_reports/models/account_generic_tax_report.py
columns_header = [{}, {'name': '%s \n %s' % (_('NET'), self.format_date(dt_to, dt_from, options)), 'class': 'number', 'style': 'white-space: pre;'}, {'name': _('TAX'), 'class': 'number'} , {'name': _('New Field'), 'class': 'number'}]
See attached image.

get grouped results with sparql query

I still feel like a SPARQL newbie, so I may be way off base about what SPARQL GROUP BY does, but here's my questions.
Suppose I wanted to request all resources in graph database called Categories, and I wanted to get all the items associated with these categories, along with the names of the items and their price.
Right now my SPARQL queries are giving me back something like the following table:
**Categories Item ItemName ItemPrice**
Tools HammerID Hammer $12
Tools SawID Saw $13
Tools WrenchID Wrench $10
Food AppleID Apple $5
Food CornID Corn $1
I wanted to use GROUP BY to group the items under a single category, so that when I start processing it, I can look through each unique category and then display the items that belong in that category.
Right now if I loop through the above results, I will be iterating over 5 entries instead of 2.
The other way I can describe the results I want are by imaging what the corresponding json data would look like. I want something like:
[
tools: [
{id: hammerId
title: hammer
price: $12},
{id: sawId
title: saw
price: $13},
{id: wrenchId
title: wrench
price: $10}
],
food: [
{id: appleId
title: apple
price: $5},
{id: cornId
title: corn
price: $1}
]
]
With the results, like this I can directly loop over the top level items, and then display the results for each.
Can I use GROUP BY to tell SPARQL to give me results like this?
No, you can't. A SPARQL SELECT query-result is defined as a sequence of solutions, with each solution being a set of variable-value pairs (with a value being defined as an IRI, BNode, or literal value). Basically it's a simple table. There is no provision for 'nested' solutions like you'd need for your JSON-like structure.
However the difference is purely syntactic. If you group, you know the result will deliver all solutions belonging to the same group together (one after the other) - so in processing the result you can simply treat the grouped variable as a marker. And of course if you really want, you can easily rewrite the query result into this kind of syntactic structure yourself - it's just a different way of writing down the exact same information, after all.

eBay API categoryId in findItemsAdvanced call returns wrong categories

I'm trying to use the categoryId in my findItemsAdvanced query:
api.execute('findItemsAdvanced', {
'keywords': 'laptop',
'categoryId': '51148'}
The results I get are, for example (printing the searchResult dictionary):
'itemId': {'value': '200971548007'}, 'isMultiVariationListing': .............
'primaryCategory': {'categoryId': {'value': '69202'}, 'categoryName': {'value': 'Air Conditioning'}}
....."
You can see that the result has a categoryId of 69202, and not 51148.
What am I doing wrong here? I'm just using the finding.py code at:
https://github.com/timotheus/ebaysdk-python
Thanks
Edit
I've done some tests. I extracted the XML that the SDK builds. If I call with:
'categoryId': '177'
The response is:
the request_xml is <?xml version='1.0' encoding='utf-8'?><findItemsAdvancedRequest
xmlns="http://www.ebay.com/marketplace/search/v1/services"><categoryId>177</categoryId>
<itemFilter><name>Condition</name><value>Used</value></itemFilter><itemFilter>
<name>LocatedIn</name><value>GB</value></itemFilter><keywords>laptop</keywords>
<paginationInput><entriesPerPage>100</entriesPerPage><pageNumber>1</pageNumber>
</paginationInput></findItemsAdvancedRequest>
and I get the same with
'categoryId': ['177']
I find this a bit odd, I thought the appropriate name for the XML categoryId was 'CategoryId' with a capital C. If I do that I don't get an error, but the result is not restricted to the categoryId requested.
Doing it like above, I still get the error:
Exception: findItemsAdvanced: Domain: Marketplace, Severity: Error,
errorId: 3, Invalid category ID.
The code below will do a keyword search for 'laptops' across the UK eBay site and restrict the search to the two categories Apple Laptops(111422) and PC Laptops & Netbooks(177). In addition the results are filtered to only show the first 25 used items that are priced between £200 and £400. The results are also sorted by price from high to low.
There are a few things to keep in mind about this example.
It assumes that you have already installed ebaysdk-python.
According to the eBay docs the categoryId field is a string and more than one category can be specified. An array is therefore used to hold the category ids that we are interested in.
Our request needs to search for items in the UK eBay site. We therefore pass EBAY-GB as the siteid parameter.
Category ids are different across each eBay site. For example the category PC Laptops & Netbooks(177) does not exist in Belgium. (Which incidently is the site that is used in the ebaysdk-python finding.py example.)
This example is also available as a Gist
import ebaysdk
from ebaysdk import finding
api = finding(siteid='EBAY-GB', appid='<REPLACE WITH YOUR OWN APPID>')
api.execute('findItemsAdvanced', {
'keywords': 'laptop',
'categoryId' : ['177', '111422'],
'itemFilter': [
{'name': 'Condition', 'value': 'Used'},
{'name': 'MinPrice', 'value': '200', 'paramName': 'Currency', 'paramValue': 'GBP'},
{'name': 'MaxPrice', 'value': '400', 'paramName': 'Currency', 'paramValue': 'GBP'}
],
'paginationInput': {
'entriesPerPage': '25',
'pageNumber': '1'
},
'sortOrder': 'CurrentPriceHighest'
})
dictstr = api.response_dict()
for item in dictstr['searchResult']['item']:
print "ItemID: %s" % item['itemId'].value
print "Title: %s" % item['title'].value
print "CategoryID: %s" % item['primaryCategory']['categoryId'].value
I hope the following will explain why performing a search on the Belgium site results in items that contain the category 177 even though this is not valid for Belgium but is valid for the UK.
Basically eBay allow sellers from one site to appear in the search results of another site as long as they meet the required criteria, such as offering international shipping. It allows sellers to sell to other countries without the need to actually list on those sites.
From the example XML that elelias provided I can see that a keyword search for 'laptop' was made on the Belgium site with the results filtered so that only items located in the UK was to be returned.
<itemFilter>
<name>LocatedIn</name>
<value>GB</value>
</itemFilter>
Because the search was limited to those located in the UK you won't see any Belgium items in the results. Since the items where listed on the UK site they will contain information relevant to the UK. For example the category id 177. eBay does not convert the information to make it relevant to the site that you are searching on.
It is important to remember that what ever you are trying to do with the Finding API can also be repeated using the actual advance search on eBay. For example it is possible to re-create the issue by performing a keyword search for used items on the Belgium site.
This url is the equivalent of your code that was performing the search without specifying the category 177. As you can see from the results it returns items that where listed on the UK site but which are appearing in the Belgium site. It you click on some of the items, for example, you can even see that it displays the UK category PC Laptops & Netbooks (177) even though this does not exist on the Belgium site. This matches the results form your code where it was returning 177 but would not let you specify the same value in the request as you was searching the Belgium site.
I hope this helps.
Because categoryId is repeatable. You will need to pass an array into the call. Something like this should work.
api.execute('findItemsAdvanced', {
'keywords': 'laptop',
'categoryId': [
{'51148'}
]
}
Note: See how the itemFilter element is an array in the sample file of the SDK.
'itemFilter': [
{'name': 'Condition',
'value': 'Used'},
{'name': 'LocatedIn',
'value': 'GB'},
],