counter method does not count well - python

I have a method that tells the times that a worker makes a sale, but it does not work because it only marks me that he has made 1 but has actually done 5. Next I leave an image and the code used to guide me.
**class Worker (models.Model):**
_name = 'project_rc.worker'
sales_counter = fields.Integer (string = "Sales made", compute = "get_sales_made")
document_ids = fields.One2many (comodel_name = 'project_rc.document',
inverse_name = 'worker_id', string = 'Invoice')
def get_sales_made (self):
count = self.env ['project_rc.type_movement']. search_count ([('type_movement', '=', 'sale')])
self.counter_sale = count
**class Document (models.Model):**
type_movement_id = fields.Many2one (comodel_name = 'project_rc.type_movement', string = "Movement type")
worker_id = fields.Many2one (asdel_name = 'project_rc.worker', string = "Worker")
**class Type_Movement (models.Model):**
type_movement = fields.Selection ([('purchase', 'Purchase'), ('sale', 'Sale'), ('merma', 'Merma')], string = "Movement type")
document_ids = fields.One2many (comodel_name = 'project_rc.document', inverse_name = 'type_movimiento_id', string = 'Document')
Sample picture: https://ibb.co/vs0dw5K

The problem came from your function get_sales_made
class Worker(models.Model):
_name = 'project_rc.worker'
sales_counter = fields.Integer(string="Sales made", compute="get_sales_made")
document_ids = fields.One2many('project_rc.document', 'worker_id', string='Invoice')
#api.depends('document_ids')
def get_sales_made(self):
for rec in self:
document = rec.document_ids.filtered(lambda r: r.type_movement_id and r.type_movement_id.type_movement == 'sale')
rec.sales_counter = len(document)
class Document(models.Model):
_name = 'project_rc.document'
type_movement_id = fields.Many2one('project_rc.type_movement', string="Movement type")
worker_id = fields.Many2one('project_rc.worker', string="Worker")
class Type_Movement(models.Model):
_name = 'project_rc.type_movement'
type_movement = fields.Selection([('purchase', 'Purchase'), ('sale', 'Sale'), ('merma', 'Merma')], string="Movement type")
document_ids = fields.One2many('project_rc.document', 'type_movement_id', string='Document')

You are searching in the wrong table it should be project_rc.document
self.env['project_rc.document'].search_count([('type_movement_id.type_movement', '=', 'sale')
('worker_id', '=', rec.id)
])
Or you can simply filter document_ids to count sales.

Related

Instance Error On Foreign Key Field Django

Im stumped and need help on my function.
I have two tables student and student information. Student information is all guardian information of that student. I separated this data from the main student table so you can add as many guardians as you want to a students file with new records. The error I'm getting is as followed.
Cannot assign "'1'": "StudentInformation.studentpsid" must be a "Student" instance.
Attached you will see my code. Studentpsid in student information is a foreign key from student.
def ImportStudentGuardian(request):
AuthTokenP(request)
print("Getting student guardian data from SIS for K-8")
#Pulls K-8 Guardians
url = "removed for posting"
payload = {}
token = APIInformation.objects.get(api_name="PowerSchool")
key = token.key
headers = {'Authorization': 'Bearer {}'.format(key)}
response = requests.request("GET", url, headers=headers, data = payload)
encode_xml = response.text.encode('utf8')
xml_string = ET.fromstring(encode_xml)
students = xml_string.findall("student")
for student in students:
#XML Values
psid = student.find("id").text
try:
mother = student.find("contact").find("mother").text
except Exception:
mother = ""
try:
father = student.find("contact").find("father").text
except Exception:
father = ""
if Student.objects.filter(studentpsid=psid).exists():
print("Accessing guardian information.")
m = StudentInformation.objects.create(studentpsid=psid,guardian_name = mother, relation = "Mom") <---- Function Fails here
print("Record doesn't exist for mom, creating record.")
m.save()
d= StudentInformation.objects.create(studentpsid=psid,guardian_name = father, relation = "Dad")
print("Record doesn't exist for dad, creating record.")
d.save()
return ("Updated Guardian Information ")
Model
class Student(models.Model):
studentpsid= models.CharField(primary_key = True , default = "", max_length = 50, unique = True)
student_name = models.CharField(max_length = 50)
first_name = models.CharField(max_length = 50, default = "")
last_name = models.CharField(max_length = 50,default = "")
gender = models.CharField(max_length = 1,default = "")
student_grade = models.CharField(max_length = 2, default = "")
home_room = models.CharField(max_length = 5, default = "")
student_enrollment = models.CharField(max_length = 2, default = "")
school_number = models.CharField(max_length = 15, default = "")
email = models.EmailField(default = "")
projected_graduation_year = models.CharField(max_length = 4, default = "")
counseling_goal = models.TextField(max_length = 255)
class_name = models.ManyToManyField(TeacherClass)
image = models.ImageField(default ="default.png", upload_to ='student_pics')
# Guardian Information For Student
class StudentInformation(models.Model):
studentpsid = models.ForeignKey(Student,on_delete = models.CASCADE, default = "" ,)
guardian_name = models.CharField(max_length = 50, default = "")
RELATION_CHOICES = [
(0, 'None'),
(1, 'Mom'),
(2, 'Dad'),
(3, 'Other'),
]
relation = models.PositiveSmallIntegerField(choices = RELATION_CHOICES,)
guardian_cell = models.CharField(max_length = 12, default = "")
guardian_email = models.EmailField(max_length = 80,blank = True, default = "")
prefered_contact = models.BooleanField(default = False, blank = True)
DAY_CHOICES = [
(0, 'None'),
(1, 'Monday'),
(2, 'Tuesday'),
(3, 'Wednesday'),
(4, 'Thursday'),
(5, 'Friday'),
]
day_of_week = models.PositiveSmallIntegerField(choices = DAY_CHOICES, default = 0 )
time = models.CharField(max_length= 7, default = "", blank = True)
While creating a record with the foreign key relation, and instance of the related table should be provided, so the table can maintain a relationship for that particular record.
Get the instance of the Student table with the given psid and use that while creating the StudentInformation record
EDIT : Included the part for creating the record only if mother and father values are available.
for student in students:
#XML Values
psid = student.find("id").text
try:
psid_obj = Student.objects.get(studentpsid=psid) #(pk = psid) also works as the field is primary key
try:
mother = student.find("contact").find("mother").text
m = StudentInformation.objects.create(studentpsid=psid_obj,guardian_name = mother, relation = "Mom")
m.save()
except Exception as err1:
print "Error at Mom", str(err1)
try:
father = student.find("contact").find("father").text
d= StudentInformation.objects.create(studentpsid=psid_obj,guardian_name = father, relation = "Dad")
d.save()
except Exception as err2:
print "Error at Dad",str(err2)
except:
print "Student Record Not found"
As the error says, you are assigning a char data type to the ForeignKey field.
You should first get the instance of that Student, and then assign it to your StudentInformation object, like this:
if Student.objects.filter(studentpsid=psid).exists():
print("Accessing guardian information.")
student = Student.objects.get(pk=psid) # this will fail if the student doesn't exist
m = StudentInformation.objects.create(studentpsid=student,guardian_name = mother, relation = "Mom") <---- Function Fails here
print("Record doesn't exist for mom, creating record.")
m.save()
d= StudentInformation.objects.create(studentpsid=student,guardian_name = father, relation = "Dad")
print("Record doesn't exist for dad, creating record.")
d.save()
return ("Updated Guardian Information ")

Expected singleton error occurs when return more than one record in odoo?

This method to get the product price from the PO, and it works well if the PO have only one record otherwise I am getting this error.
raise ValueError("Expected singleton: %s" % self)
This is the method
#api.multi
def create_refund_invoice(self):
inv_obj = self.env['account.invoice']
for pick in self.filtered(lambda x:x.return_type):
type = 'in_refund' if pick.return_type == 'purchase' else 'out_refund'
inv_lines = {'type':type, 'partner_id':pick.partner_id.id, 'invoice_line_ids':[]}
account = pick.return_type == 'sale' and pick.partner_id.property_account_receivable_id.id or pick.partner_id.property_account_payable_id.id
inv_lines['account_id'] = account
inv_lines['origin'] = pick.name
inv_lines['name'] = pick.origin
for line in pick.move_lines:
name = line.product_id.partner_ref
for rec in self:
rec.order_id = line.env['purchase.order'].search([('name', '=', line.origin)]).order_line
rec.price = rec.order_id.price_unit
inv_lines['invoice_line_ids'] += [(0, None, {
'product_id':line.product_id.id,
'name':name,
'quantity':line.quantity_done,
'price_unit': rec.price,
'account_id':line.product_id.product_tmpl_id.get_product_accounts()['income'].id})]
if inv_lines['invoice_line_ids']:
inv_id = inv_obj.create(inv_lines)
pick.invoice_id = inv_id.id
It is necessary for odoo that when you are getting more than one record then you can not access it's field values directly.
In your code you are trying to get purchase_order_line of purchase_order It may possible that many lines are available in a single order.
def create_refund_invoice(self):
purchase_order_obj = self.env['purchase.order']
inv_obj = self.env['account.invoice']
for pick in self.filtered(lambda x:x.return_type):
type = 'in_refund' if pick.return_type == 'purchase' else 'out_refund'
inv_lines = {'type':type, 'partner_id':pick.partner_id.id, 'invoice_line_ids':[]}
account = pick.return_type == 'sale' and pick.partner_id.property_account_receivable_id.id or pick.partner_id.property_account_payable_id.id
inv_lines['account_id'] = account
inv_lines['origin'] = pick.name
inv_lines['name'] = pick.origin
for line in pick.move_lines:
name = line.product_id.partner_ref
for rec in self:
order_lines = purchase_order_obj.search([('name', '=', line.origin)]).order_line
for pol in order_lines:
price = pol.order_id.price_unit
inv_lines['invoice_line_ids'] += [(0, None, {
'product_id':line.product_id.id,
'name':name,
'quantity':line.quantity_done,
'price_unit': price,
'account_id':line.product_id.product_tmpl_id.get_product_accounts()['income'].id})
]
if inv_lines['invoice_line_ids']:
inv_id = inv_obj.create(inv_lines)
pick.invoice_id = inv_id.id
I have updated code test above code and update it as per your requirement.

In Odoo 10,how can I specify a data in create_date,create_uid,instead of value in system,when I use method named 'create' to create a record

I create new record with the method named create() in local database with data pulled away from remote database.As we all know,there are four normal fields in Odoo such as create_date,write_date,create_uid,write_uid.I want these data to be in a remote databaseļ¼Œbut when I use method named create() to create the record,these data are the data at the time of local creation and not the remote data.
For example,in remote database,the creat_date is '2019-10-11',I can't change the value that is finally written to the local database even if I pass the value of the remote database into the dictionary.Finally,the value of field named create_date is '2019-12-03' rather than '2019-10-11'.The '2019-12-03' is the date now.The situation is similar for other fields such as write_date,create_uid,write_uid.
Please help me,thanks to everyone who thought about this question.
Following is my code.
The Class Model
class ReportRentalIncomeFromProperty(models.Model):
_name = 'report.rental.income.from.property'
_description = 'The report about the income from property rental'
_order = 'product_id, start_date'
# create_date = fields.Datetime('Created on')
create_uid = fields.Char('Created by')
# write_date = fields.Datetime('Last Modified on')
write_uid = fields.Char('Last Contributor')
product_id = fields.Many2one('product.product', 'Property House')
area_id = fields.Many2one('res.country.area', 'City')
district_id = fields.Many2one('res.country.district', 'District')
town_id = fields.Many2one('res.country.town', 'Town')
road_name = fields.Char('Road')
start_date = fields.Date('Start Date')
end_date = fields.Date('End Date')
should_pay = fields.Float('Should Pay')
real_pay = fields.Float('Real Pay')
balance_pay = fields.Float('Balance Pay')
rental_compliance_rate = fields.Float('Rental Compliance Rate(%)', group_operator="avg")
company_id = fields.Many2one('res.company', string='Company')
parent_company_id = fields.Many2one('res.company', related='company_id.parent_id', store=True,
string='Parent Company')
actual_business = fields.Many2many(
'rh.commercial.activities',
'house_rental_rent_income_business_db',
'actual_business_id',
'commercial_activities_id',
string='Actual business')
The function to pull away remote data to create new record in local database.
#api.multi
def synchronization_contract_performance_rate(self):
self.env['report.rental.income.from.property'].search([]).unlink()
product_dict = {}
A_product = self.env['product.product'].search([])
for a in A_product:
product_dict[a.name] = a.id
activities_dict = {}
D_activities = self.env['rh.commercial.activities'].search([])
for d in D_activities:
activities_dict[d.name] = d.id
address_dict = {}
i = 0
address_model_list = ['res.country.area', 'res.country.district', 'res.country.town']
address_field_list = ['area_id', 'district_id', 'town_id']
for addr in address_model_list:
C_address = self.env[addr].search([])
addr_dict = {}
for c in C_address:
addr_dict[c.name] = c.id
address_dict[i] = addr_dict
i += 1
record_list_1 = self.company_recursive_func()
for list_1 in record_list_1:
database = list_1[0]
link_url = list_1[1]
if link_url.startswith('http://'):
_uri = link_url.replace('http://', '')
my_odoo = odoorpc.ODOO(_uri, port=48080)
if link_url.startswith('https://'):
_uri = link_url.replace('https://', '')
my_odoo = odoorpc.ODOO(_uri, port=443, protocol='jsonrpc+ssl')
username = list_1[2]
password = list_1[3]
my_odoo.login(database, username, password)
company_id = list_1[4]
company_code = list_1[5]
product_actual_business_dict = {}
A_product_actual_business_ids = my_odoo.env['product.product'].search([])
A_product_actual_business = my_odoo.execute('product.product', 'read', A_product_actual_business_ids,
['actual_business'])
for a in A_product_actual_business:
name_list = []
for b in my_odoo.execute('rh.commercial.activities', 'read', a.get('actual_business'), ['name']):
name_list.append(b.get('name'))
product_actual_business_dict[a.get('id')] = name_list
remote_ids = my_odoo.env['report.rental.income.from.property'].search([])
remote_data_dict = my_odoo.execute('report.rental.income.from.property', 'read', remote_ids, ['product_id',
'start_date',
'create_date',
'create_uid',
'write_date',
'write_uid',
'end_date',
'should_pay',
'balance_pay',
'real_pay',
'rental_compliance_rate',
'area_id',
'road_name',
'district_id',
'town_id'])
for data in remote_data_dict:
remote_product_name = data.get('product_id')[1]
product_id = product_dict.get(remote_product_name + '(' + company_code + ')',
None)
if product_id:
i = 0
address_id_list = []
for address_field in address_field_list:
if data.get(address_field):
remote_address_name = data.get(address_field)[1]
local_address_id = address_dict[i].get(remote_address_name, None)
address_id_list.append(local_address_id)
else:
address_id_list.append(None)
i += 1
ids_list = []
find_names = product_actual_business_dict.get(data.get('product_id')[0])
for find_name in find_names:
id = activities_dict.get(find_name, None)
if id:
ids_list.append(id)
value = {
'product_id': product_id,
'area_id': address_id_list[0],
'district_id': address_id_list[1],
'town_id': address_id_list[2],
'road_name': data['road_name'],
'start_date': data['start_date'],
'end_date': data['end_date'],
'should_pay': data['should_pay'],
'real_pay': data['real_pay'],
'create_date': data['create_date'],
'create_uid': data['create_uid'][1],
'write_date': data['write_date'],
'write_uid': data['write_uid'][1],
'balance_pay':data['balance_pay'],
'rental_compliance_rate': data['rental_compliance_rate'],
'company_id': company_id,
'actual_business': [(6, 0, ids_list)]
}
self.env['report.rental.income.from.property'].create(value)
my_odoo.logout()
You can change standart odoo fields after you create your record with sql query
property_id = self.env['report.rental.income.from.property'].create(value)
self.env.cr.execute("UPDATE report_rental_income_from_property SET create_date='%s', create_uid=%s, write_date='%s', write_uid=%s WHERE id=%s" %
(value['create_date'], value['create_uid'], value['write_date'], value['write_uid'], property_id))

Arrange nested dict items Python

I have written this code and it is fine, but the output of the dict is not what i want. Here is the code:
class EbExportCustomer(models.Model):
_inherit = 'res.partner'
#api.one
def get_pa_data(self):
aValues = defaultdict(dict)
aValues['partner_id'] = self.id
aValues['name'] = self.name
aValues['street'] = self.street
aValues['street2'] = self.street2
aValues['zip'] = self.zip
aValues['city'] = self.city
aValues['country'] = self.country_id.name
aValues['state'] = self.state_id.name
aValues['email'] = self.email
aValues['website'] = self.website
aValues['phone'] = self.phone
aValues['mobile'] = self.mobile
aValues['fax'] = self.fax
aValues['language'] = self.lang
aValues['child_ids']['name'] = []
aValues['child_ids']['function'] = []
aValues['child_ids']['email'] = []
if self.child_ids:
for child in self.child_ids:
aValues['child_ids']['name'].append(child.name)
aValues['child_ids']['function'].append(child.function)
aValues['child_ids']['email'].append(child.email)
return aValues
I am currently using dicttoxml and collections.defaultdict, The output is this:
<Partner><item>
<website>http://www.chinaexport.com/</website>
<city>Shanghai</city>
<fax>False</fax>
<name>China Export</name>
<zip>200000</zip>
<mobile>False</mobile>
<country>China</country>
<street2>False</street2>
<child_ids>
<function>
<item>Marketing Manager</item>
<item>Senior Consultant</item>
<item>Order Clerk</item>
<item>Director</item>
</function>
<name>
<item>Chao Wang</item>
<item>David Simpson</item>
<item>Jacob Taylor</item>
<item>John M. Brown</item>
</name>
<email><item>chao.wang#chinaexport.example.com</item> \ <item>david.simpson#epic.example.com</item><item>jacob.taylor#millennium.example.com</item><item>john.brown#epic.example.com</item></email></child_ids><phone>+86 21 6484 5671</phone><state>False</state><street>52 Chop Suey street</street><language>en_US</language><partner_id>9</partner_id><email>chinaexport#yourcompany.example.com</email>
But i would need the output for child_ids to be like:
<child_id>
< function >
Marketing
Manager
</function>
< name >Chao
Wang </ name >
< email > chao.wang # chinaexport.example.com </ email>
</child id>
And then another <child id> with the fields from all the other child ids.
Thanks in advance.
You want a single list (of dictionaries, probably), rather than three parallel lists. Something like this:
aValues['child_ids'] = []
for child in self.child_ids:
aValues['child_ids'].append({
'name': child.name,
'function': child.function,
'email': child.email
})

Dynamically change dropdown options for one field, after setting another field in a dexterity form.Schema

i'm failing at dynamically changing the dropdown options for one field, after setting another field in a dexterity form.Schema.
the vocabularies are based in a sql database.
specifically i want to update the vocabulary options for township after selecting the county.
right now i am just pulling the full list of townships regardless of the country selected. as all attempts to dynamically change things led to errors.
any help on this would be appreciated. thanks!
from site.py:
from selectionProvider import SelectionProvider
vocabProvider = SelectionProvider()
#grok.provider(IContextSourceBinder)
def countySource(context):
return vocabProvider.getVocabulary('county')
#grok.provider(IContextSourceBinder)
def townshipSource(context):
return vocabProvider.getVocabulary('township')
class IESurrenderSite(form.Schema):
county = schema.Choice(
title=_(u"County"),
source=countySource,
required=True,
)
township = schema.Choice(
title=_(u"Township"),
source=townshipSource,
required=True,
)
...
from selectiorProvider.py:
class SelectionProvider(object):
DB = maap_db.maap_db()
vocabularies = {}
Counties = {}
Townships = {}
def getCountiesDropdownRecordSet(self, object):
"""input:object is a string
"""
print 'in getCountiesDropdownRecordSet'
self.DB.open()
rs = self.DB.RunQuery("Select *, CountyID as [value], name as [title] From County Order By name;")
self.DB.close()
SelectionProvider.CountiesByName = {}
for rec in rs:
SelectionProvider.CountiesByName[rec['CountyID']] = rec['title']
#
return rs
def getTownshipDropdownRecordSet(self, object):
"""input:object is a string
"""
print 'in getTownshipDropdownRecordSet'
self.DB.open()
rs = self.DB.RunQuery("Select *, TownshipID as [value], name as [title] From Township Order By name;")
self.DB.close()
SelectionProvider.TownshipsByName = {}
for rec in rs:
SelectionProvider.TownshipsByName[rec['TownshipID']] = rec['title']
#
return rs
# #
def getDropdownRecordSet(self, object):
"""input:object is a string
"""
print 'in getDropdownRecordSet'
self.DB.open()
rs = self.DB.RunQuery("Select * From DropdownSelections Where object = '%s' Order By seqNo;" % (object))
self.DB.close()
return rs
def buildVocabulary(self, rs, valueField='value', titleField='title'):
"""DO NOT USE directly outside this class, see getVocabulary() or rebuildVocabulary() instead
"""
data = []
for rec in rs:
data.append(SimpleTerm(value=rec[valueField], title=_(rec[titleField])))
#
return SimpleVocabulary(data)
#
def rebuildVocabulary(self, object):
"""Force a fetch from the database and rebuild the vocabulary.
input object: a string, matches the DropdownSelections field
"""
print 'initializing %s' % (object)
if object=="county":
print 'going to CountiesDropdowns'
vocab = self.buildVocabulary(self.getCountiesDropdownRecordSet(object), "CountyID","title")
SelectionProvider.vocabularies[object] = vocab
return vocab
if object=="township":
print 'going to TownshipDropdowns'
vocab = self.buildVocabulary(self.getTownshipDropdownRecordSet(object), "TownshipID","title")
SelectionProvider.vocabularies[object] = vocab
#print _SITE_NAME, '%s selection list initialized.' % (object)
return vocab
else:
vocab = self.buildVocabulary(self.getDropdownRecordSet(object))
SelectionProvider.vocabularies[object] = vocab
return vocab
def getVocabulary(self, object):
"""Retrieve cached vocabulary
input object: a string, matches the DropdownSelections field
"""
recreate = False
if not SelectionProvider.vocabularies.has_key(object):
recreate = True
#
vocab = SelectionProvider.vocabularies.get(object)
if vocab == None or len(vocab) == 0:
recreate = True
#
if recreate:
vocab = self.rebuildVocabulary(object)
#
return vocab
You can do this with plone.formwidget.masterselect
Like this (untested, but gives you an idear of how it works):
from zope import schema
from plone.supermodel import model
from plone.formwidget.masterselect import _
from plone.formwidget.masterselect import MasterSelectBoolField
from plone.formwidget.masterselect import MasterSelectField
def getTownshipDynVocab(master):
CountryID = master_value
# search for your township entries by CountryID
# and return it as a DisplayList
return townshipDynamicVocab
class IESurrenderSite(model.Schema):
county = MasterSelectField(
title=_(u"County"),
source=countySource,
slave_fields=(
# Controls the vocab of township
{'name': 'township',
'action': 'vocabulary',
'vocab_method': getTownshipDynVocab,
},
),
required=True,
)
township = schema.Set(
title=_(u"Township"),
value_type=schema.Choice(),
required=False,
)

Categories