If there is only one product in memo_data['items'] the sale order line will be created but if there are two or more products it will be reefused with an error: Too many values to unpack.
Here is the code:
for item in memo_data['items']:
c_id = self.env['sale.order.line'].search([('creditmemo_id','=',memo_data['creditmemo_id'])])
if not c_id:
_logger.info("THIS IS CID: %s" % memo_data['creditmemo_id'])
a_product = self.env['product.product'].search([('default_code', '=',item['sku'])])
if a_product:
_logger.info("FOUND THE PRODUCT with id: %s" %a_product.id)
pos_price = float(item['row_total'])
neg_price = pos_price - (2 * pos_price)
res12 = {
'order_id': is_exist.id,
'product_id': a_product.id,
'price_unit': neg_price,
'sequence': 10,
'product_uom_qty': float(item['qty']),
'creditmemo_id' : memo_data['creditmemo_id'],
'creditmemo_date': memo_data['created_at'],
'creditmemo_increment_id' : memo_data['increment_id'],
}
self.env['sale.order.line'].create(res12)`enter code here`
i assume you are trying to loop the list of records. but inside loop try to change memo_data to item:
for item in memo_data['items']:
c_id = self.env['sale.order.line'].search([('creditmemo_id','=',item['creditmemo_id'])])
if not c_id:
_logger.info("THIS IS CID: %s" % item['creditmemo_id'])
a_product = self.env['product.product'].search([('default_code', '=',item['sku'])])
if a_product:
_logger.info("FOUND THE PRODUCT with id: %s" %a_product.id)
pos_price = float(item['row_total'])
neg_price = pos_price - (2 * pos_price)
res12 = {
'order_id': is_exist.id,
'product_id': a_product.id,
'price_unit': neg_price,
'sequence': 10,
'product_uom_qty': float(item['qty']),
'creditmemo_id' : item['creditmemo_id'],
'creditmemo_date': item['created_at'],
'creditmemo_increment_id' : item['increment_id'],
}
I think you need to handle your dict like this
for field, possible_values in fields.iteritems():
print field, possible_values
python 2.7 : iteritems()
python 3: items().
Thanks
Related
I am trying to fetch Rally data by using its python library pyral. Sequentially the same code works, but its slow.
I thought of using python multiprocess package, however my pool.apply method gets stuck and never executes. I tried running it in Pycharm IDE as well as the windows cmd prompt.
import pandas as pd
from pyral import Rally
from multiprocessing import Pool, Manager
from pyral.entity import Project
def process_row(sheetHeaders: list, item: Project, L: list):
print('processing row : ' + item.Name) ## this print never gets called
row = ()
for header in sheetHeaders:
row.append(process_cell(header, item))
L.append(row)
def process_cell(attr, item: Project):
param = getattr(item, attr)
if param is None:
return None
try:
if attr == 'Owner':
return param.__getattr__('Name')
elif attr == 'Parent':
return param.__getattr__('ObjectID')
else:
return param
except KeyError as e:
print(e)
# Projects
# PortfolioItem
# User Story
# Hierarchical Req
# tasks
# defects
# -------------MAIN-----------------
def main():
# Rally connection
rally = Rally('rally1.rallydev.com', apikey='<my_key>')
file = 'rally_data.xlsx'
headers = {
'Project': ['Name', 'Description', 'CreationDate', 'ObjectID', 'Parent', 'Owner', 'State'],
}
sheetName = 'Project'
sheetHeaders = headers.get(sheetName)
p = Pool(1)
result = rally.get(sheetName, fetch=True, pagesize=10)
with Manager() as manager:
L = manager.list()
for item in result:
print('adding row for : ' + item.Name)
p.apply_async(func=process_row, args=(sheetHeaders, item, L)) ## gets stuck here
p.close()
p.join()
pd.DataFrame(L).to_excel(file, sheet_name=sheetName)
if __name__ == '__main__':
main()
Also tried without Manager list without any difference in the outcome
def main():
# Rally connection
rally = Rally('rally1.rallydev.com', apikey='<key>')
file = 'rally_data.xlsx'
headers = {
'Project': ['Name', 'Description', 'CreationDate', 'ObjectID', 'Parent', 'Owner', 'State'],
}
sheetName = 'Project'
sheetHeaders = headers.get(sheetName)
result = rally.get(sheetName, fetch=True, pagesize=10)
async_results = []
with Pool(50) as p:
for item in result:
print('adding row for : ' + item.Name)
async_results.append(p.apply_async(func=process_row, args=(sheetHeaders, item)))
res = [r.get() for r in async_results]
pd.DataFrame(res).to_excel(file, sheet_name=sheetName)
I dont know why, but replacing multiprocessing
with multiprocessing.dummy in the import statement worked.
I have this function it filters in all selected MO's raw material lines, and then creates a report that is displayed in tree view.
But I have one problem, there can be allot lines with the same product. So my goal is to group all these lines and display them then just in one line with summed quantity.
Can someone help me with this?
class RawMaterialReport(models.Model):
_name = 'raw.material.report'
_description = 'Raw Material Report'
product_id = fields.Many2one('product.product', string='Product', required=False)
code = fields.Char(string='Code', required=True, readonly=True)
total_qty = fields.Float(string='Total Qty', digits=(6, 2), readonly=True)
virtual_qty = fields.Float(string='Forcasted Qty', digits=(6, 2), readonly=True)
origin = fields.Char(string='Origin', required=True, readonly=True)
production_id = fields.Many2one('mrp.production')
#api.multi
def open_raw_materials(self):
self.search([]).unlink()
mrp_productions = self._context.get('active_ids')
mrp_production = self.env['mrp.production'].browse(mrp_productions)
products_without_default_code = mrp_production.mapped('move_raw_ids').filtered(
lambda x: not x.product_id.default_code
)
raws = mrp_production.mapped('move_raw_ids').sorted(
key=lambda r: r.product_id.default_code
)
for r in raws:
vals = {
'product_id': r.product_id.id,
'code': r.product_id.default_code,
'total_qty': r.product_id.qty_available,
'virtual_qty': r.product_id.virtual_available,
'origin': r.reference,
'production_id': r.raw_material_production_id.id,
}
self.create(vals)
Instead of creating the record directly, keep them in dictionary grouped by product ID and when ever you find that the product all ready have a record just sum its
quantity.
#api.multi
def open_raw_materials(self):
self.search([]).unlink()
mrp_productions = self._context.get('active_ids')
mrp_production = self.env['mrp.production'].browse(mrp_productions)
products_without_default_code = mrp_production.mapped('move_raw_ids').filtered(
lambda x: not x.product_id.default_code
)
raws = mrp_production.mapped('move_raw_ids').sorted(
key=lambda r: r.product_id.default_code
)
# to group by product
recs = {}
for r in raws:
product_id = self.product_id.id
if product_id in recs:
# here just update the quantities or any other fields you want to sum
recs[product_id]['product_uom_qty'] += self.product_id.product_uom_qty
else:
# keep the record in recs
recs[product_id] = {
'product_id': r.product_id.id,
'code': r.product_id.default_code,
'total_qty': r.product_id.product_uom_qty,
'virtual_qty': r.product_id.virtual_available,
'origin': r.reference,
'production_id': r.raw_material_production_id.id,
}
for vals in recs.values():
# create records this will create a record by product
self.create(vals)
Given the following input:
* def list = [{a: 'aaa', b:'bbb'}, {a:'aa', c:'ccc'}]
* def anotherList = [{a: 'aaa', b:'bbb'}, {a:'aa', b:'', c:'ccc'}]
* def msg = {b: '#string'}
How to check that b key is present only once?
Using:
* match list contains '#(^msg)'
will validate that there is at least one occurrence of b in list.
How to check that there is exactly one occurrence of key b in list or in anotherList? So such check should pass for list and fail for anotherList.
You can filter with a match and a contains short-cut:
* def list = [{ a: 'aaa', b: 'bbb' }, { a: 'aa', c: 'ccc' }]
* def msg = { b: '#string' }
* def fun = function(x){ return karate.match(x, '#(^msg)').pass }
* def filt = karate.filter(list, fun)
* match filt == '#[1]'
I am trying to create a sample order in sales order.In the sample order form, products are sold to customers as complimentary copy(books in my case) without charging any money so I have created a separate sub-menu in sales menu.Here I take only product and quantity as input. Sample order number will be the next number from the sales order(like SO360).So I am fetching sales order number as parent_id in my inherited module.I am not able to create sale order line(data in order lines tab)
class SaleOrder(models.Model):
_inherit = 'sale.order'
# Fields
is_sample = fields.Boolean(string="Sample Order", default=False)
parent_id = fields.Many2one('sale.order', string="Parent Sales Order")
sample_ids = fields.One2many('sale.order', 'parent_id',
string="Sample Orders")
# Methods
#api.model
#api.returns('sale.order')
def create(self, vals):
if vals.get('is_sample', False) and vals.get('name', '/') == '/':
IrSeq = self.env['ir.sequence']
ref = IrSeq.next_by_code('sale.order.sample.ref') or '/'
parent = self.search([('id', '=', vals.get('parent_id'))])
vals['name'] = parent.name + ref
vals['user_id'] = parent.user_id.id
return super(SaleOrder, self).create(vals)
class SampleOrderWizard(models.TransientModel):
_name = 'sale.order.sample.wizard'
_description = 'Sample Sale Order Wizard'
# Field default values
#
def _get_parent(self):
res = False
if self.env.context \
and 'active_id' in list(self.env.context.iterkeys()):
res = self.env.context['active_id']
return res
def _get_new_sale_line(self, orig_sale, orig_sale_line, wizard_line):
"""Internal function to get the fields of the sale order line. Modules
enhancing this one should add their own fields to the return value."""
res = {
'order_id': orig_sale.id,
'product_id': orig_sale_line.product_id.id,
'name': orig_sale_line.name,
'sequence': orig_sale_line.sequence,
'price_unit': orig_sale_line.price_unit,
'product_uom': orig_sale_line.product_uom.id,
'product_uom_qty': wizard_line and wizard_line.qty or 0,
'product_uos_qty': wizard_line and wizard_line.qty or 0,
}
# Simple check for installation of sale_line_code module
if hasattr(orig_sale_line, 'order_line_ref'):
res.update({'order_line_ref': orig_sale_line.order_line_ref})
return res
def _get_order_lines(self, sale):
res = []
for line in sale.order_line:
wizard_line = False
for wzline in self.wizard_lines:
if wzline.product == line.product_id:
wizard_line = wzline
break
if wizard_line:
res.append(
(0, 0, self._get_new_sale_line(sale, line, wizard_line))
)
return res
def _get_wizard_lines(self):
res = []
if self._get_parent():
SaleOrder = self.env['sale.order']
parent = SaleOrder.search([('id', '=', self._get_parent())])
for line in parent.order_line:
res.append((0, 0,
{
'product': line.product_id,
'qty': 1,
}))
return res
# Fields
#
order = fields.Many2one('sale.order', default=_get_parent, readonly=True)
wizard_lines = fields.One2many('sale.order.sample.wizard.line', 'wizard',
default=_get_wizard_lines)
order_date = fields.Datetime(default=fields.Datetime.now())
# Methods
#
#api.one
def create_order(self):
sale_vals = {
'user_id': self.order.user_id.id,
'partner_id': self.order.partner_id.id,
'parent_id': self.order.id,
'date_order': self.order_date,
'client_order_ref': self.order.client_order_ref,
'company_id': self.order.company_id.id,
'is_sample': True,
'order_line': self._get_order_lines(self.order)
}
self.env['sale.order'].create(sale_vals)
return {'type': 'ir.actions.act_window_close'}
class SampleOrderWizardLine(models.TransientModel):
_name = 'sale.order.sample.wizard.line'
_description = 'Sample Order Wizard Line'
wizard = fields.Many2one('sale.order.sample.wizard')
product = fields.Many2one('product.product',
domain=[('sale_ok', '=', True)])
qty = fields.Float(string="Quantity", default=1.0,
digits_compute=dp.get_precision('Product UoS'))
Currently I am developing a tool by using Python with Gtk+ library. And I met an issue here as $subject. Is there any effective way for changing the treestore "1/8"'s background color to red ? Something like the below image:
http://imagebin.ca/v/1pZgJ61cWi9D
I use treestore.set_value to change it, but unfortunately it does not work for me, it can only change the value of the treestore.
No idea about it so I raise a question here.
Can anybody keep an eye of it ? Any suggestions that would be appreciated.
you can use documents of pygtk2.0 about TreeViewColumn.set_cell_data_func method and read important page about CellRenderers and special properties of PyGTK2.0 that also is useful on version 3 of PyGTK :)
Below code can helping you:
#!/usr/bin/env python
try:
import pygtk; pygtk.require('2.0')
except:
pass
import gtk
import pango
COL_FIRST_NAME = 0
COL_LAST_NAME = 1
COL_YEAR_BORN = 2
COL_COLOR = 3
class TreeStoreExample:
def createAndFillModel(self):
treestore = gtk.TreeStore(str, str, str, str)
toplevel1 = treestore.append(None)
toplevel2 = treestore.append(None)
child = treestore.append(toplevel2)
pre_child = treestore.append(child)
tree = [(toplevel1,
COL_FIRST_NAME, "Maria",
COL_LAST_NAME, "Incognito",
COL_YEAR_BORN, 1982,
COL_COLOR, 'black'),
(toplevel2,
COL_FIRST_NAME, "Jane",
COL_LAST_NAME, "Average",
COL_YEAR_BORN, 1962,
COL_COLOR, 'black'),
(child,
COL_FIRST_NAME, "Janinita",
COL_LAST_NAME, "Average",
COL_YEAR_BORN, 1985,
COL_COLOR, 'black'),
(pre_child,
COL_FIRST_NAME, "ABC",
COL_LAST_NAME, "DEF",
COL_COLOR, 'black')
]
year_now = 2015
for item in tree:
iter = item[0]
treestore.set(*item)
if item[5] == COL_COLOR:
treestore.set_value(iter, COL_YEAR_BORN, "age unknown")
for x in range(1, len(treestore.get_path(iter)) + 1):
niter = treestore.get_iter(treestore.get_path(iter)[:x])
treestore.set_value(niter, COL_COLOR, "red")
else:
treestore.set_value(iter, COL_YEAR_BORN, year_now - item[6])
return treestore
def ageCellDataFunc(self, column, renderer, model, iter, data):
year_now = 2015
year_born = model.get_value(iter, COL_YEAR_BORN)
if year_born and year_born <= year_now:
age = year_now - year_born
buf = "%u years old" % age
renderer.set_property("foreground-set", gtk.FALSE)
else:
buf = "age unknown"
#renderer.set_property("foreground", "red")
model.set_value(iter, COL_COLOR, "red")
for x in range(1, len(model.get_path(iter))):
niter = model.get_iter(model.get_path(iter)[:x])
node = model.set_value(niter, COL_COLOR, "red")
print model.get_path(iter)[:x], ":", model.get_value(niter, COL_COLOR)
#renderer.set_property("text", buf)
def createViewAndModel(self):
view = gtk.TreeView(self.createAndFillModel())
self.view = view
# --- Column 1 ---
column = gtk.TreeViewColumn()
column.set_title("First Name")
view.append_column(column)
renderer = gtk.CellRendererText()
column.pack_start(renderer, gtk.TRUE)
column.add_attribute(renderer, "text", COL_FIRST_NAME)
# --- Column 2 ---
column = gtk.TreeViewColumn()
column.set_title("Last Name")
view.append_column(column)
renderer = gtk.CellRendererText()
column.pack_start(renderer, gtk.TRUE)
column.add_attribute(renderer, "text", COL_LAST_NAME)
renderer.set_property("weight", pango.WEIGHT_BOLD)
# --- Column 3 ---
renderer = gtk.CellRendererText()
renderer.set_property('foreground-set',True)
column = gtk.TreeViewColumn("age", renderer, foreground=COL_COLOR)
column.pack_start(renderer, gtk.TRUE)
column.add_attribute(renderer, "text", COL_YEAR_BORN)
column.add_attribute(renderer, "foreground", COL_COLOR)
#column.set_title("age")
view.append_column(column)
#column.set_cell_data_func(renderer, self.ageCellDataFunc, None)
#model = self.createAndFillModel()
#view.set_model(model)
view.get_selection().set_mode(gtk.SELECTION_NONE)
return view
def __init__(self):
window = gtk.Window(gtk.WINDOW_TOPLEVEL)
window.connect("delete_event", gtk.mainquit)
view = self.createViewAndModel()
window.add(view)
window.show_all()
def main():
gtk.main()
return 0
if __name__ == "__main__":
TreeStoreExample()
main()
The ageCellDataFunc method not run because if set set_cell_data_func then add_attribute method not running.