I am trying to create an invoice from a custom object but I am getting errors from on validation .When I post, i get the following error: "
ValueError: Wrong value for account.move.line_ids: {'display_type': 'line_section', 'name': 'Phone Bill', 'product_id': 11783, 'product_uom_id': 19, 'current_reading': 66.0, 'current_date': datetime.date(2020, 11, 3), 'quantity': 17.0, 'price_unit': 565.0, 'account_id': 19, 'debit': 9605.0, 'credit': 0.0}
current_date and current_reading are custom fields i created. I am aware that Odoo automatically creates values for line_ids from invoice_line_ids if line_ids is not provided, so I am really stuck about this error.
Here's my code for creating the invoice:
class ReadingCorrection(models.TransientModel):
_name = 'reading.upload.wizard'
_description = 'Validate reading uploads'
def validate_entry(self):
active_ids = self._context.get('active_ids', []) or []
company = self.env.user.company_id
journal = self.env['account.move'].with_context(force_company=company.id, type='out_invoice')._get_default_journal()
for reads in self.env['reading.upload'].browse(active_ids):
if reads.reading >= reads.previous_reading: # and reads.state == 'draft':
account = reads.product_id.product_tmpl_id._get_product_accounts()['income']
if not account:
raise UserError(_('No account defined for product "%s".') % reads.product_id.name)
invoice = {
'type': 'out_invoice',
'invoice_date':reads.read_date,
'narration': reads.remark,
'invoice_user_id': reads.current_user.id,
'partner_id': reads.meter_id.customer_id.id,
'journal_id': 1,#journal.id,
'currency_id': reads.meter_id.customer_id.currency_id.id,
'doc_type': 'bill',
'invoice_line_ids':[(0,0, {
'name': reads.product_id.name,
'product_id': reads.product_id.id,
'product_uom_id': reads.product_id.uom_id.id,
'current_reading': reads.reading,
'previous_reading': reads.previous_reading,
'current_date': reads.read_date,
'quantity': reads.reading - reads.previous_reading,
'price_unit': reads.product_id.product_tmpl_id.lst_price,
'account_id': account.id,
})]
}
moves = self.env['account.move'].with_context(default_type='out_invoice').create(invoice)
#invoice = self.env['account.move'].sudo().create(invoice)
reads.write({'state':'uploaded'})
Any help given will be appreciated. Thanks
If you want to create invoices, in the lines you should not use the debit and credit fields since these are calculated, as it is a product line, you should not use display_type, since the line_section type is treated as an annotation and not as a price calculation line.
In the invoice data, when linking the lines 'invoice_line_ids': inv_line_ids an instruction must be specified to process the lines in your case it would be as follows 'invoice_line_ids': (0, 0, inv_line_ids) for greater information visit this page.
My objective is to extract info from site https://shopopenings.com/merchant-search after entering pin code of the respective area and copy all info from there. Whether outlet is opened or closed. There has to be loop.
This site has an underlying API that you can use to get JSON responses. To find the endpoints and what is expected as request and response you can use the Mozilla developer tools and Chrome devtools under network.
import json
import requests
SEARCH_ADDRESS = "California City, CA 93505"
urlEndpoint_AutoComplete = "https://shopopenings.com/api/autocomplete"
urlEndpoint_Search = "https://shopopenings.com/api/search"
search_Location = {"type":"address", "searchText":SEARCH_ADDRESS, "language":"us"}
locations = requests.post(urlEndpoint_AutoComplete, data=search_Location)
local = json.loads(locations.text)[0] # get first address
local["place_address"] = local.pop("name") # fix key name for next post request
local["place_id"] = local.pop("id") # fix key name for next post request
local["shopTypes"] = ["ACC", "ARA", "AFS", "AUT", "BTN", "BWL", "BKS", "AAC",
"CEA", "CSV", "DPT", "DIS", "DSC", "DLS", "EQR", "AAF", "GHC", "GRO", "HBM",
"HIC", "AAM", "AAX", "MER", "MOT", "BMV", "BNM", "OSC", "OPT", "EAP", "SHS",
"GSF", "SGS", "TEV", "TOY", "TAT", "DVG", "WHC", "AAW"]
local["range"] = 304.8
local["language"] = "us"
results = requests.post(urlEndpoint_Search, data=local)
print(json.loads(results.text))
{'center': {'latitude': 35.125801, 'longitude': -117.9859038},
'range': '304.8',
'merchants': [{'mmh_id': '505518130',
'latitude': 35.125801,
'longitude': -117.9859,
'shopName': 'Branham M Branham Mtr',
'shopFullAddressString': 'California City, CA',
'isOpen': False,
'nfc': False,
'shopType': 'AUT',
'distance': 0.34636329,
'country': 'USA'},
{'mmh_id': '591581670',
'latitude': 35.125442,
'longitude': -117.986083,
'shopName': 'One Stop Market',
'shopFullAddressString': '7990 California City Blvd, California City, CA 93505-2518',
'isOpen': True,
'nfc': True,
'shopType': 'AFS',
'distance': 43.04766933,
'country': 'USA'},
...
...
I think use selenium to control the Navigation and the entering of the Pin then use BeautifulSoup to work with the Page Source after you action. Here is the documentation it's easy enough to get you started.
Selenium -- https://selenium-python.readthedocs.io/
BeautifulSoup -- https://readthedocs.org/projects/beautiful-soup-4/
Enjoy!!
I am looking to get the value of the description field inside the weather.
{'coord': {'lon': 73.85, 'lat': 18.52}, 'weather': [{'id': 800, 'main': 'Clear', 'description': 'clear sky', 'icon': '01d'}], 'base': 'stations', 'main': {'temp': 305.381, 'pressure': 949.7, 'humidity': 31, 'temp_min': 305.381, 'temp_max': 305.381, 'sea_level': 1023.73, 'grnd_level': 949.7}
i have seen many posts and i am trying to do the below:
r1 = requests.get('http://api.openweathermap.org/data/2.5/weather?q=Pune,in&APPID=5ad6ec2537bfb0d574363e115c2d0041')
print(r1.status_code)
json_data = json.loads(r1.text)
print(json_data)
print("Weather is" ,json_data["weather"][0])
But the above is fetching me all the values inside the dictionary.
What's the best way to achieve that?
Thanks.
Use json_data["weather"][0]['description'] to access the description field.
I have the following python code that is to replace low-precision temperatures in a list of JSON trees, ec2_tcs['zones'] with higher precision temps from a generator, ec1_api.temperatures().
if CONF_HIGH_PRECISION:
try:
from evohomeclient import EvohomeClient as EvohomeClientVer1
ec1_api = EvohomeClientVer1(client.username, client.password)
for temp in ec1_api.temperatures(force_refresh=True):
for zone in ec2_tcs['zones']:
if str(temp['id']) == str(zone['zoneId']):
if zone['temperatureStatus']['isAvailable']:
zone['temperatureStatus']['temperature'] \
= temp['temp']
break
# TypeError: usually occurs in client library if problems with vendor's website
except TypeError:
_LOGGER.warning(
"Failed to obtain higher-precision temperatures"
)
The JSON data looks like this (an array of JSON data, 1 per 'zone'):
[
{
'zoneId': '3432521',
'name': 'Main Room'
'temperatureStatus': {'temperature': 21.5, 'isAvailable': True},
'setpointStatus': {'targetHeatTemperature': 5.0, 'setpointMode': 'FollowSchedule'},
'activeFaults': [],
}, {
...
...
}
]
and each result from the generator like this:
{'thermostat': 'EMEA_ZONE', 'id': 3432521, 'name': 'Main Room', 'temp': 21.55, 'setpoint': 5.0}
I know Python must have a better way of doing this, but I can't seem to make it fly. Any suggestions would be gratefully received.
I could 'massage' the generator, but there are good reasons why the JSON tree's schema should remain unchanged.
The primary goal is to reduce a number of nested code blocks with a very fancy one-liner!
I have this csv file with only two entries. Here it is:
Meat One,['Abattoirs', 'Exporters', 'Food Delivery', 'Butchers Retail', 'Meat Dealers-Retail', 'Meat Freezer', 'Meat Packers']
First one is title and second is a business headings.
Problem lies with entry two.
Here is my code:
import csv
with open('phonebookCOMPK-Directory.csv', "rt") as textfile:
reader = csv.reader(textfile)
for row in reader:
row5 = row[5].replace("[", "").replace("]", "")
listt = [(''.join(row5))]
print (listt[0])
it prints:
'Abattoirs', 'Exporters', 'Food Delivery', 'Butchers Retail', 'Meat Dealers-Retail', 'Meat Freezer', 'Meat Packers'
What i need to do is that i want to create a list containing these words and then print them like this using for loop to print every item separately:
Abattoirs
Exporters
Food Delivery
Butchers Retail
Meat Dealers-Retail
Meat Freezer
Meat Packers
Actually I am trying to reformat my current csv file and clean it so it can be more precise and understandable.
Complete 1st line of csv is this:
Meat One,+92-21-111163281,Al Shaheer Corporation,Retailers,2008,"['Abattoirs', 'Exporters', 'Food Delivery', 'Butchers Retail', 'Meat Dealers-Retail', 'Meat Freezer', 'Meat Packers']","[[' Outlets Address : Shop No. Z-10, Station Shopping Complex, MES Market, Malir-Cantt, Karachi. Landmarks : MES Market, Station Shopping Complex City : Karachi UAN : +92-21-111163281 '], [' Outlets Address : Shop 13, Ground Floor, Plot 14-D, Sky Garden, Main Tipu Sultan Road, KDA Scheme No.1, Karachi. Landmarks : Nadra Chowrangi, Sky Garden, Tipu Sultan Road City : Karachi UAN : +92-21-111163281 '], ["" Outlets Address : Near Jan's Broast, Boat Basin, Khayaban-e-Roomi, Block 5, Clifton, Karachi. Landmarks : Boat Basin, Jans Broast, Khayaban-e-Roomi City : Karachi UAN : +92-21-111163281 View Map ""], [' Outlets Address : Gulistan-e-Johar, Karachi. Landmarks : Perfume Chowk City : Karachi UAN : +92-21-111163281 '], [' Outlets Address : Tee Emm Mart, Creek Vista Appartments, Khayaban-e-Shaheen, Phase VIII, DHA, Karachi. Landmarks : Creek Vista Appartments, Nueplex Cinema, Tee Emm Mart, The Place City : Karachi Mobile : 0302-8333666 '], [' Outlets Address : Y-Block, DHA, Lahore. Landmarks : Y-Block City : Lahore UAN : +92-42-111163281 '], [' Outlets Address : Adj. PSO, Main Bhittai Road, Jinnah Supermarket, F-7 Markaz, Islamabad. Landmarks : Bhittai Road, Jinnah Super Market, PSO Petrol Pump City : Islamabad UAN : +92-51-111163281 ']]","Agriculture, fishing & Forestry > Farming equipment & services > Abattoirs in Pakistan"
First column is Name
Second column is Number
Third column is Owner
Forth column is Business type
Fifth column is Y.O.E
Sixth column is Business Headings
Seventh column is Outlets (List of lists containing every branch address)
Eighth column is classification
There is no restriction of using csv.reader, I am open to any technique available to clean my file.
Think of it in terms of two separate tasks:
Collect some data items from a ‘dirty’ source (this CSV file)
Store that data somewhere so that it’s easy to access and manipulate programmatically (according to what you want to do with it)
Processing dirty CSV
One way to do this is to have a function deserialize_business() to distill structured business information from each incoming line in your CSV. This function can be complex because that’s the nature of the task, but still it’s advisable to split it into self-containing smaller functions (such as get_outlets(), get_headings(), and so on). This function can return a dictionary but depending on what you want it can be a [named] tuple, a custom object, etc.
This function would be an ‘adapter’ for this particular CSV data source.
Example of deserialization function:
def deserialize_business(csv_line):
"""
Distills structured business information from given raw CSV line.
Returns a dictionary like {name, phone, owner,
btype, yoe, headings[], outlets[], category}.
"""
pieces = [piece.strip("[[\"\']] ") for piece in line.strip().split(',')]
name = pieces[0]
phone = pieces[1]
owner = pieces[2]
btype = pieces[3]
yoe = pieces[4]
# after yoe headings begin, until substring Outlets Address
headings = pieces[4:pieces.index("Outlets Address")]
# outlets go from substring Outlets Address until category
outlet_pieces = pieces[pieces.index("Outlets Address"):-1]
# combine each individual outlet information into a string
# and let ``deserialize_outlet()`` deal with that
raw_outlets = ', '.join(outlet_pieces).split("Outlets Address")
outlets = [deserialize_outlet(outlet) for outlet in raw_outlets]
# category is the last piece
category = pieces[-1]
return {
'name': name,
'phone': phone,
'owner': owner,
'btype': btype,
'yoe': yoe,
'headings': headings,
'outlets': outlets,
'category': category,
}
Example of calling it:
with open("phonebookCOMPK-Directory.csv") as f:
lineno = 0
for line in f:
lineno += 1
try:
business = deserialize_business(line)
except:
# Bad line formatting?
log.exception(u"Failed to deserialize line #%s!", lineno)
else:
# All is well
store_business(business)
Storing the data
You’ll have the store_business() function take your data structure and write it somewhere. Maybe it’ll be another CSV that’s better structured, maybe multiple CSVs, a JSON file, or you can make use of SQLite relational database facilities since Python has it built-in.
It all depends on what you want to do later.
Relational example
In this case your data would be split across multiple tables. (I’m using the word “table” but it can be a CSV file, although you can as well make use of an SQLite DB since Python has that built-in.)
Table identifying all possible business headings:
business heading ID, name
1, Abattoirs
2, Exporters
3, Food Delivery
4, Butchers Retail
5, Meat Dealers-Retail
6, Meat Freezer
7, Meat Packers
Table identifying all possible categories:
category ID, parent category, name
1, NULL, "Agriculture, fishing & Forestry"
2, 1, "Farming equipment & services"
3, 2, "Abattoirs in Pakistan"
Table identifying businesses:
business ID, name, phone, owner, type, yoe, category
1, Meat One, +92-21-111163281, Al Shaheer Corporation, Retailers, 2008, 3
Table describing their outlets:
business ID, city, address, landmarks, phone
1, Karachi UAN, "Shop 13, Ground Floor, Plot 14-D, Sky Garden, Main Tipu Sultan Road, KDA Scheme No.1, Karachi", "Nadra Chowrangi, Sky Garden, Tipu Sultan Road", +92-21-111163281
1, Karachi UAN, "Near Jan's Broast, Boat Basin, Khayaban-e-Roomi, Block 5, Clifton, Karachi", "Boat Basin, Jans Broast, Khayaban-e-Roomi", +92-21-111163281
Table describing their headings:
business ID, business heading ID
1, 1
1, 2
1, 3
…
Handling all this would require a complex store_business() function. It may be worth looking into SQLite and some ORM framework, if going with relational way of keeping the data.
You can just replace the line :
print(listt[0])
with :
print(*listt[0], sep='\n')