OpenERP create & write methods at once - python

Here is my error when i'm going to create records.please advice me where is the missing point.?
File "/home/bellvantage/Documents/openerp-7.0/openerp-7/openerp/addons/bpl/bpl.py", line 394, in create
self.write(cr, uid, [id], {'name': name}, context)
File "/usr/lib/python2.7/dist-packages/psycopg2/extensions.py", line 129, in getquoted
pobjs = [adapt(o) for o in self._seq]
ProgrammingError: can't adapt type 'builtin_function_or_method'
2013-04-26 06:14:07,719 5739 INFO demo werkzeug: 127.0.0.1 - - [26/Apr/2013 06:14:07] "POST /web/dataset/call_kw HTTP/1.1" 200 -
relevant line in my code is like this
def create(self, cr, uid, values, context=None):
name = 'CheckRoll No : ' + str(values['checkroll_no']) + ' & Gang No : ' + str(values['gang_no'])
self.write(cr, uid, [id], {'name': name}, context)
return True
error comes and shows that my write method is incorrect.seems some parameter missing by me.
needs your advices to implement module
thanks..
EDITED
Now error like below
File "/home/bellvantage/Documents/openerp-7.0/openerp-7/openerp/addons/bpl/bpl.py", line 395, in create
res = super('bpl.work.offer',self).create(cr,uid,values,context=context)
TypeError: must be type, not str
2013-04-26 07:58:43,452 6947 INFO demo werkzeug: 127.0.0.1 - - [26/Apr/2013 07:58:43] "POST /web/dataset/call_kw HTTP/1.1" 200 -
here shows my fields in model class
'name': fields.char('Name', size=50),
'checkroll_no': fields.integer('Checkroll No'),
'gang_no': fields.integer('Gang'),
here shows values when i debug (at super.create() time),
dict: {'selected_tea_workers_line_ids': [[5, False, False], [0, False, {'worker_emp_no': '1000', 'worker_id':
1, 'tea_line_worker_id': False, 'is_selected': False}]], 'user_id': False, 'is_confirmed': False,
'date_of_offer': '2013-04-26', 'bpl_division_id': 1, 'work_type': 'tea', 'checkroll_no': 10, 'name':
'CheckRoll No : 10 & Gang No : 100', 'selected_rubber_workers_line_ids': [[5, False, False], [0, False,
{'worker_emp_no': '1001', 'worker_id': 2, 'rubber_line_worker_id': False, 'is_selected': False}]],
'work_update_id': False, 'field_no': 15, 'selected_sundry_workers_line_ids': [], 'payment_type':
'normal_work', 'gang_no': 100, 'total_workers': 0, 'no_of_workers': 0, 'norm': 15,
'selected_other_workers_line_ids': [], 'bpl_estate_id': 1, 'select_by': 'by_name'}
now its worked. thanks AnomA
Last Edited
def create(self, cr, uid, values, context=None):
name = 'CheckRoll No = ' + str(values['checkroll_no']) + ' & Gang No = ' + str(values['gang_no'])
values.update({'name': name})
return super(bpl_work_offer,self).create(cr,uid,values,context=context)

Actually you are doing wrong. You are trying to write to a record that is not created.Also I dont think you need to use write in this case.
class bpl_abc(osv.osv)
_inherit = 'bpl.work.offer'
def create(self, cr, uid, values, context=None):
name = 'CheckRoll No : ' + str(values['checkroll_no']) + ' & Gang No : ' + str(values['gang_no'])
values.update({'name': name})
res = super('bpl_abc',self).create(cr,uid,values,context=context)
return res
bpl_abc()
Please keep in mind that create function in openerp always return an id of the newly created record.

May be because 'write' method is the built-in method
EX:
with open("a.txt","r+") as f:
f.write("sometext")
Don't use self.write as write is the built-in method on 'file' object

Related

Odoo Accounting Report returning IndexError: list index out of range

I'm developing a custom accounting report on Odoo Enterprise. It's first time I try to do this kind of report, so I have a lot of doubts that I haven't solved on internet.
Based on native reports I came to this so far:
class BudgetaryPositionCompanyReport(models.AbstractModel):
_name = "budgetary.position.report"
_inherit = "account.report"
filter_date = {'date_from': '', 'date_to': '', 'filter': 'this_month'}
filter_unfold_all = False
def _get_columns_name(self, options):
return [{'name': _('Budget Item')}, {'name': _('Column1')}, {'name': _('Column2')}, {'name': _('%')}]
#api.model
def _get_lines(self, options, line_id=None):
context = dict(self._context or {})
date_from = context.get('date_from')
date_to = context.get('date_to')
lines = []
sql_parents = """
SELECT abp.name "name", sum(cbl.planned_amount) planned_amount, sum(cbl.r_practical_amount) r_practical_amount, sum(cbl.r_percentage) r_percentage
FROM crossovered_budget_lines cbl
JOIN account_budget_post abp ON (cbl.general_budget_id = abp.id)
GROUP BY abp.id;
"""
self.env.cr.execute(sql_parents)
results_parents = self.env.cr.dictfetchall()
for parent in results_parents:
lines.append({
'id': parent.get('id'),
'name': parent.get('name'),
'level': 1,
'unfoldable': True,
'unfolded': True,
'colspan': 4,
'columns': [
{'name': parent.get('name') and parent.get('name')},
{'name': parent.get('planned_amount') and self.format_value(parent.get('planned_amount'))},
{'name': parent.get('r_practical_amount') and self.format_value(parent.get('r_practical_amount'))},
{'name': parent.get('r_percentage') and self.format_value(parent.get('r_percentage'))}
],
})
print(lines)
return lines
def _get_report_name(self):
return _('Budgetary Positions (per company)')
def _get_templates(self):
templates = super(BudgetaryPositionCompanyReport, self)._get_templates()
return templates
Problem is when I try to access to this report, I'm getting the following:
Error to render compiling AST
IndexError: list index out of range
Template: account_reports.line_template
Path: /templates/t/t/tr/t[2]/td
Node: <td t-att-class="'o_account_report_line ' + (column.get('class', lines.get('columns_header')[-1][column_index+line.get('colspan', 1)].get('class', '')) + (line.get('unfoldable') and ' o_foldable_total' or '')) + ('' if hierarchies_enabled else ' o_account_report_line_indent')" t-att-style="column.get('style', lines.get('columns_header')[-1][column_index+line.get('colspan', 1)].get('style', ''))">
<span class="o_account_report_column_value" t-att-title="column.get('title')">
<t t-esc="column.get('name')"/>
</span>
</td>
Am I missing something?

Converting dictionary values into a string object with a specific order

I am looking to create a function that will turn a dictionary with address values into a string value with a specific order. I also need to account for missing values (Some address wont have a second or third address line. I want my output to look like the below so that I can copy the text block, separated by a new line, into a database field.
name
contact
addr1
addr2 (if not empty)
addr3 (if not empty)
city, state zip
phone
I have the following to create the dictionary, but I am stuck on creating the string object that ignores the empty values and puts everything in the correct order.
def setShippingAddr(name, contact, addr1, addr2, addr3, city, state, zipCode, phone):
addDict = {'name': name, 'contact': contact, 'addr1': addr1,
'city': city, 'state': state, 'zip': zipCode, 'phone': phone}
if addr2 is True: # append dict if addr2/addr 3 are True
addDict['addr2'] = addr2
if addr3 is True:
addDict['addr3'] = addr3
shAddr = # This is where i need to create the string object
return shAddr
I would rewrite the function to only return the string, the dictionary is not necessary:
def setShippingAddr(name, contact, addr1, city, state, zipCode, phone, addr2=None, addr3=None):
shAddr = f'{name}\n{contact}\n{addr1}'
shAddr = f'{shAddr}\n{addr2}' if addr2 else shAddr
shAddr = f'{shAddr}\n{addr3}' if addr3 else shAddr
shAddr = f'{shAddr}\n{city}, {state} {zipCode}\n{phone}'
return shAddr
Considering that you may want to add new entries to the dictionary
def setShippingAddr(name, contact, addr1, addr2, addr3, city, state, zipCode, phone):
addDict = {'name': name, 'contact': contact, 'addr1': addr1,
'city': city, 'state': state, 'zip': zipCode, 'phone': phone}
if addr2 is True: # append dict if addr2/addr 3 are True
addDict['addr2'] = addr2
if addr3 is True:
addDict['addr3'] = addr3
shAddr = ''
for key in addDict:
shAddr += addDict[key] + '\n'
return shAddr
It looks like (assuming you're using python3), an f string would work here.
shAddr = f"{addDict['name']} {addDict['contract'] etc..."
You can add logic within the {}, so something like
{addDict['addr2'] if addDict['addr2'] else ""}
should work, depending on what the specific output you were looking for was.
I'm not sure I understand the part with the dictionary. You could just leave it out, right?
Then
def setShippingAddr(*args):
return "\n".join([str(arg) for arg in args if arg])
s = setShippingAddr("Delenges", "Me", "Streetstreet", "Borrough", False,
"Town of City", "Landcountry", 12353, "+1 555 4545454")
print(s)
prints
Delenges
Me
Streetstreet
Borrough
Town of City
Landcountry
12353
+1 555 4545454
Here's a more pythonic solution,
def dict_to_string(dic):
s = ''
for k, v in dic.items():
s += "{} : {}\n".format(k, v)
return s
addDict = {'name': 'name', 'contact': 'contact', 'addr1': 'addr1', 'addr2': '',
'city': 'city', 'state': 'state', 'zip': 'zipCode', 'phone': 'phone'}
print(dict_to_string(addDict))
In this case, I've used addr2, which has a blank value. If you want, addr2 to be omitted completely, then check for the value while iterating.
def dict_to_string(dic):
s = ''
for k, v in dic.items():
if k:
s += "{} : {}\n".format(k, v)
return s
addDict = {'name': 'name', 'contact': 'contact', 'addr1': 'addr1', 'addr2': '',
'city': 'city', 'state': 'state', 'zip': 'zipCode', 'phone': 'phone'}
print(dict_to_string(addDict))
Finally if the natural order of iterating is not what you want you can use the OrderedDict

ODOO8: Untaxed and total amount in order lines not calculating

I add multiple PRODUCTS in the order lines of the REPAIR-ORDER, the price of each product shows up - but the untaxed sub total and total display (0) instead of the total of all products.
I've attached some of the code of the MRP REPAIR (.py) file :
def _amount_all_wrapper_repair(self, cr, uid, ids, field_name, arg, context=None):
""" Wrapper because of direct method passing as parameter for function fields """
return self._amount_all_repair(cr, uid, ids, field_name, arg, context=context)
def _amount_all_repair(self, cr, uid, ids, field_name, arg, context=None):
cur_obj = self.pool.get('res.currency')
res = {}
for order in self.browse(cr, uid, ids, context=context):
res[order.id] = {
'amount_untaxed': 0.0,
'amount_tax': 0.0,
'amount_total': 0.0,
}
val = val1 = 0.0
cur = order.sale_id.pricelist_id.currency_id
for line in order.order_line_ids:
val1 += line.price_subtotal
val += self._amount_line_tax_repair(cr, uid, line, context=context)
res[order.id]['amount_tax'] = cur_obj.round(cr, uid, cur, val)
res[order.id]['amount_untaxed'] = cur_obj.round(cr, uid, cur, val1)
res[order.id]['amount_total'] = res[order.id]['amount_untaxed'] + res[order.id]['amount_tax']
return res
The code for the mrp_repair.xml:
<group class="oe_subtotal_footer oe_right" colspan="2" name="sale_total">
<field name="amount_untaxed" widget='monetary' options="{'currency_field': 'currency_id'}"/>
<field name="amount_tax" widget='monetary' options="{'currency_field': 'currency_id'}"/>
<div class="oe_subtotal_footer_separator oe_inline">
<label for="amount_total" />
<button name="button_dummy"
states="draft,sent" string="(update)" type="object" class="oe_edit_only oe_link"/>
</div>
<field name="amount_total" nolabel="1" class="oe_subtotal_footer_separator" widget='monetary' options="{'currency_field': 'currency_id'}"/>
<div class="oe_inline" groups="garage.group_display_margin">
<label for="margin" style="font-weight:bold;"/>
</div>
<field name="margin" nolabel="1" style="font-weight:bold;" groups="garage.group_display_margin"/>
</group>
EDIT - Added info
I found that without the code below (this code causes MRP_REPAIR to add order lines both to the REPAIR ORDER and SALES ORDER), adding a product with a price doesnt get calculated in total field, and shows zero (0)
elif this.repair_sale_order_line_id:
sale_obj = self.pool.get('sale.order')
so_vals = {
'partner_id' : this.repair_sale_order_line_id.partner_id.id,
'fleet_id': this.repair_sale_order_line_id.fleet_id.id,
'responsable_id': uid,
}
created_so_id = so_obj.create(cr, uid, so_vals, context=context)
sol_vals = {'order_id': created_so_id,
'price_unit': this.price_unit,
'product_uom_qty': this.product_uom_qty,
'price_subtotal': this.price_subtotal,
'discount': this.discount,
'product_id': this.product_id.id,
'tax_id': [(6, 0, [x.id for x
in this.tax_id])],
'name': this.name,
}
self.pool.get('mrp.repair').write(cr, uid, this.repair_sale_order_line_id.id, {'sale_id':created_so_id},context=context)
sol_id = sol_obj.create_sol(cr, uid, sol_vals, context)
super(repair_sale_order_line, self).write(cr, uid, [res],{'sale_order_line_id':sol_id})
it seems that the Sale Order lines are used instead of the internal Repair Sale Order lines. The question is: how can i make the mrp not depend on the SO or its ORDER LINES.?
I found that without the code below (this code causes MRP_REPAIR to add order lines both to the REPAIR ORDER and SALES ORDER), adding a product with a price doesnt get calculated in total field, and shows zero (0)
elif this.repair_sale_order_line_id:
sale_obj = self.pool.get('sale.order')
so_vals = {
'partner_id' : this.repair_sale_order_line_id.partner_id.id,
'fleet_id': this.repair_sale_order_line_id.fleet_id.id,
'responsable_id': uid,
}
created_so_id = so_obj.create(cr, uid, so_vals, context=context)
sol_vals = {'order_id': created_so_id,
'price_unit': this.price_unit,
'product_uom_qty': this.product_uom_qty,
'price_subtotal': this.price_subtotal,
'discount': this.discount,
'product_id': this.product_id.id,
'tax_id': [(6, 0, [x.id for x
in this.tax_id])],
'name': this.name,
}
self.pool.get('mrp.repair').write(cr, uid, this.repair_sale_order_line_id.id, {'sale_id':created_so_id},context=context)
sol_id = sol_obj.create_sol(cr, uid, sol_vals, context)
super(repair_sale_order_line, self).write(cr, uid, [res],{'sale_order_line_id':sol_id})
it seems that the Sale Order lines are used instead of the internal Repair Sale Order lines. The question is: how can i make the mrp not depend on the SO or its ORDER LINES.?

Extract the list of running IP's from AWS

I need to exactract a list of all Running IP's from AWS and along the list of IP i also want the tag-value & the region-name(or availability-zone). The list should look as follows
ex : [[('23.1.1.141', ' Production LB', 'us-east-1'), ('47.2.14.93', 'sung2-cloud-trial01-LBi-b89671', 'us-west-2'),................]]
The list consists of the following:
<'Running IP'>,<'Tag-value'>,<AvailabilityZone>
Using boto3 and I can achieve this using describe_instances(), so I tried using it as follows:
def gather_public_ip():
regions = ['us-west-2', 'eu-central-1', 'ap-southeast-1']
combined_list = [] ##This needs to be returned
for region in regions:
instance_information = {}
ip_dict = {}
client = boto3.client('ec2', aws_access_key_id=ACCESS_KEY, aws_secret_access_key=SECRET_KEY,
region_name=region, )
instance_dict = client.describe_instances().get('Reservations')
for instance in instance_dict:
.....
#WHAT CODE COMES HERE???
gather_public_ip()
So what exactly should i be looking into for this ? I am not sure how to do so, please help
NEW ANSWER RESPONSE:
Traceback (most recent call last):
File "C:/Users/nisingh/PycharmProjects/untitled1/more_specific.py", line 35, in <module>
gather_public_ip()
File "C:/Users/nisingh/PycharmProjects/untitled1/more_specific.py", line 27, in gather_public_ip
ipaddress = instance['PublicIpAddress'] # Which one do you need?
KeyError: 'PublicIpAddress'
{u'Monitoring': {u'State': 'disabled'}, u'PublicDnsName': '', u'RootDeviceType': 'ebs', u'State': {u'Code': 80, u'Name': 'stopped'}, u'EbsOptimized': False, u'LaunchTime': datetime.datetime(2015, 5, 2, 16, 34, 17, tzinfo=tzutc()), u'PrivateIpAddress': '10.11.32.10', u'ProductCodes': [], u'VpcId': 'vpc-8ae766ef', u'StateTransitionReason': 'User initiated (2016-01-29 22:20:18 GMT)', u'InstanceId': 'i-5e8ae8a8', u'ImageId': 'ami-5189a661', u'PrivateDnsName': 'ip-10-11-32-10.us-west-2.compute.internal', u'KeyName': 'pdx01-cump-050215', u'SecurityGroups': [{u'GroupName': 'pdx01-clv-jumpeng', u'GroupId': 'sg-50abbf35'}], u'ClientToken': 'inYin1430584456904', u'SubnetId': 'subnet-57e45b20', u'InstanceType': 't2.micro', u'NetworkInterfaces': [{u'Status': 'in-use', u'MacAddress': '06:91:7c:86:7c:d5', u'SourceDestCheck': True, u'VpcId': 'vpc-8ae766ef', u'Description': 'Primary network interface', u'NetworkInterfaceId': 'eni-7d566d0b', u'PrivateIpAddresses': [{u'Primary': True, u'PrivateIpAddress': '10.11.32.10'}], u'Attachment': {u'Status': 'attached', u'DeviceIndex': 0, u'DeleteOnTermination': True, u'AttachmentId': 'eni-attach-08d40929', u'AttachTime': datetime.datetime(2015, 5, 2, 16, 34, 17, tzinfo=tzutc())}, u'Groups': [{u'GroupName': 'pdx01-cloud-dev-jumpeng', u'GroupId': 'sg-50abbf35'}], u'SubnetId': 'subnet-57e45b20', u'OwnerId': '547316675291', u'PrivateIpAddress': '10.11.32.10'}], u'SourceDestCheck': True, u'Placement': {u'Tenancy': 'default', u'GroupName': '', u'AvailabilityZone': 'us-west-2b'}, u'Hypervisor': 'xen', u'BlockDeviceMappings': [{u'DeviceName': '/dev/sda1', u'Ebs': {u'Status': 'attached', u'DeleteOnTermination': True, u'VolumeId': 'vol-0990f21b', u'AttachTime': datetime.datetime(2015, 5, 2, 16, 34, 21, tzinfo=tzutc())}}], u'Architecture': 'x86_64', u'StateReason': {u'Message': 'Client.UserInitiatedShutdown: User initiated shutdown', u'Code': 'Client.UserInitiatedShutdown'}, u'RootDeviceName': '/dev/sda1', u'VirtualizationType': 'hvm', u'Tags': [{u'Value': 'pdx01-jump02-DEPRECATED', u'Key': 'Name'}, {u'Value': 'Cloud Eng Jump Box', u'Key': 'Description'}], u'AmiLaunchIndex': 0}
I think it is all about finding the information in the response and grabbing it;
def gather_public_ip():
regions = ['us-west-2', 'eu-central-1', 'ap-southeast-1']
combined_list = [] ##This needs to be returned
for region in regions:
instance_information = [] # I assume this is a list, not dict
ip_dict = {}
client = boto3.client('ec2', aws_access_key_id=ACCESS_KEY, aws_secret_access_key=SECRET_KEY,
region_name=region, )
instance_dict = client.describe_instances().get('Reservations')
for reservation in instance_dict:
for instance in reservation['Instances']: # This is rather not obvious
if instance[unicode('State')][unicode('Name')] == 'running':
try:
ipaddress = instance[unicode('PublicIpAddress')]
except:
break
tagValue = instance[unicode('Tags')][0][unicode('Value')] # 'Tags' is a list, took the first element, you might wanna switch this
zone = instances[unicode('Placement')][unicode('AvailabilityZone')]
info = ipaddress, tagValue, zone
instance_information.append(info)
combined_list.append(instance_information)
return combined_list
gather_public_ip()
I hope this is what you are looking for, and I also hope you do NOT copy this straight off, but look at how I extracted the info from the return dict in the docs.
Try ip_addr = instance_dict['Reservations'][0]['Instances'][0]['PublicIpAddress'] for IP addresses. describe_instaces() response is a dictionary whose value is an array which conatins multiple other dictionaries and so on....

Edit keys from a python object - getting TypeError: iteration over non-sequence

When I print out my variable
print myOptions
I get
{'verbose': False,
'number': '1',
'asgMaxSize': '?dev = 2 | ?qa = 2 | ? prd = 8',
'availabilityZone': 'us-east-1a,us-east-1e',
'securityGroups': ['bouncebox-member', 'bouncebox-member'],
'\
instanceType': '?dev = m3.medium | ?qa = m3.medium | ?prd = m3.medium',
'runcommon': False,
'zone': 'inpwrd.net',
'bubblewrapp': False,
'healthCheckTarget': 'HTTP:8080/:NAME:/api/health-check',
'environment': 'dev',
'application': 'tint',
'nscustomerdata': None,
'ami': 'ami-8a5d81e2',
'userData': 'defaultUserData.txt',
'outputFile': None,
'description': 'tint - replacement thumbscraper stack',
'desiredCapacity': '1',
'securityPorts': 'httpPort8080,sshPort',
'instanceProfile': 'default-:ENV:1',
'elbListeners': 'http8080',
'name': 'tint',
'blockDeviceMap': 'Empty',
'instanceMonitoring': 'false',
'asgMinSize': '1',
'keyname': None,
'alarms': 'diskspace,memory,tint'}
(line breaks added for readability)
So it looks like a key/value pair to me. I want to iterate through it like this:
for key in myOptions:
if key == "instanceProfile":
myOptions.value = myOptions.value.replace(":ENV:", "dev")
But when I run the code I get "TypeError: iteration over non-sequence"
So, how do I determine what Type the object is and how can I walk through the key/value pair (dictionary?) that is there?
I am using python version 2.7.8 if that make a difference.
When I print out "print myOptions.class" I get "optparse.Values"
The construction of myOptions is
from optparse import OptionParser
_opt = OptionParser("%prog [options] configfiles...")
_opt.add_option("-v", "--verbose", ...)
_opt.add_option("-r", "--runcommon", ...)
.... a bunch of _opt.add_option
import shlex
def parse(filename, defaults):
myopt, args = _opt.parse_args(shlex.split(open(filename).read()), defaults)
return myopt
if __name__ == "__main__":
import sys
myOptions, args = _opt.parse_args()
myOptions = parse("default.ini", myOptions)
for arg in args:
myOptions = parse(arg, myOptions)
myOptions, args = _opt.parse_args(values = myOptions)
argConfigurationName = args[-1]
if (myOptions.name == None):
myOptions.name = argConfigurationName
if myOptions.verbose == True:
print "Configuration Variables"
for name in _opt.defaults:
print "\t", name, "=", getattr(myOptions, name)

Categories