copying custom field value from sale order line to stock.move in odoo - odoo-10

Copying value from sale order line to stock move it shows only second row value in both rows. code:
[enter image description here][1]
from odoo import models, fields, api
class StockMove(models.Model):
#api.multi
def get_data(self):
data = self.env['sale.order.line'].search([])
print("Get Data Function")
for rec in data:
print(rec.x_serialnumber)
for record in self:
record.x_serialnumber = rec.x_serialnumber
_inherit = 'stock.move'
x_serialnumber = fields.Text(string="Serial Number", compute='get_data')"
On Sale order line it shows like this:
Serial Number: in both lines
112233
445566
But in stock move:
Serial Number: in both lines
445566
445566

Aurangzaib
Update your code:
#api.multi
def get_data(self):
for move in self:
if not (move.picking_id and move.picking_id.group_id):
continue
picking = move.picking_id
sale_order = self.env['sale.order'].sudo().search([
('procurement_group_id', '=', picking.group_id.id)], limit=1)
for line in sale_order.order_line:
if line.product_id.id != move.product_id.id:
continue
move.update({
'x_serialnumber': line.x_serialnumber,
})

Related

problems with the leaderboard discord.py

The leaderboard shows the same username even if they are different users in case they have the same value.
I don't know how to solve it but when in the code I ask to resist a variable it gives me only 3 elements and not 4 even if 4 come out.
code:
#client.command(aliases = ["lb"])
async def leaderboard(ctx,x = 10):
leader_board = {}
total = []
for user in economy_system:
name = int(user)
total_amount = economy_system[user]["wallet"] + economy_system[user]["bank"]
leader_board[total_amount] = name
total.append(total_amount)
print(leader_board)
total = sorted(total,reverse=True)
embed = discord.Embed(
title = f"Top {x} Richest People",
description = "This is decided on the basis of raw money in the bank and wallet",
color = 0x003399
)
index = 1
for amt in total:
id_ = leader_board[amt]
member = client.get_user(id_)
name = member.name
print(name)
embed.add_field(
name = f"{index}. {name}",
value = f"{amt}",
inline = False
)
if index == x:
break
else:
index += 1
await ctx.send(embed=embed)
print resists this:
{100: 523967502665908227, 350: 554617490806800387, 1100: 350886488235311126}
Padre Mapper
Flore (Orsolinismo)
Aetna
Aetna
In theory there should also be 100: 488826524791734275 (i.e. my user id) but it doesn't find it.
Your problem comes from this line:
leader_board[total_amount] = name
If total_amount is already a key (eg. two users have the same amount of money), it will replace the previous value (which was a user ID) and replace it with another user ID. In this situation, if multiple users have the same amount of money, only one will be saved in leader_board.
Then, you have this line:
total.append(total_amount)
In this case, if two users have the same amount of money, you would just have two identical values, which is normal but, considering the problem above, this will create a shift.
Let's say you have ten users with two of them who have the same amount of money. leader_board will only contain 9 items whereas total will contain 10 values. That's the reason why you have two of the same name in your message.
To solve the problem:
#client.command(aliases = ["lb"])
async def leaderboard(ctx, x=10):
d = {user_id: info["wallet"] + info["bank"] for user_id, info in economy_system.items()}
leaderboard = {user_id: amount for user_id, amount in sorted(d.items(), key=lambda item: item[1], reverse=True)}
embed = discord.Embed(
title = f"Top {x} Richest People",
description = "This is decided on the basis of raw money in the bank and wallet",
color = 0x003399
)
for index, infos in enumerate(leaderboard.items()):
user_id, amount = infos
member = client.get_user(user_id)
embed.add_field(
name = f"{index}. {member.display_name}",
value = f"{amount}",
inline = False
)
await ctx.send(embed=embed)
If I guessed right and your dictionnary is organized like this, it should work:
economy_system = {
user_id: {"bank": x, "wallet": y}
}

how to add symbols to the multiple stock data

#i have scraped data below is my code, now i want to add a column of symbols to the respective company data, plz guide me how the symbol can be added to the respective firm data
#code below
from time import sleep
import pandas as pd
import os
import numpy as np
from bs4 import BeautifulSoup
from selenium import webdriver
from webdriver_manager.chrome import ChromeDriverManager
browser = webdriver.Chrome(ChromeDriverManager().install())
symbols =['FATIMA',
'SSGC',
'FCCL',
'ISL',
'KEL',
'NCL',
'DGKC',
'SNGP',
'NML',
'ENGRO',
'HUMNL',
'CHCC',
'ATRL',
'HUBC',
'ASTL',
'PIBTL',
'OGDC',
'EFERT',
'FFC',
'NCPL',
'KTML',
'PSO',
'LUCK',
'SEARL',
'KOHC',
'ABOT',
'AICL',
'HASCOL',
'PTC',
'KAPCO',
'PIOC',
'POL',
'SHEL',
'GHGL',
'HCAR',
'DCR',
'BWCL',
'MTL',
'GLAXO',
'PKGS',
'SHFA','MARI',
'ICI',
'ACPL',
'PSMC',
'SPWL',
'THALL',
'BNWM',
'EFUG',
'GADT',
'AABS']
company = 1
for ThisSymbol in symbols :
# Get first symbol from the above python list
company = 2
# In the URL, make symbol as variable
url = 'http://www.scstrade.com/stockscreening/SS_CompanySnapShotYF.aspx?symbol=' + ThisSymbol
browser.get(url)
sleep(2)
# The below command will get all the contents from the url
html = browser.execute_script("return document.documentElement.outerHTML")
# So we will supply the contents to beautiful soup and we tell to consider this text as a html, with the following command
soup = BeautifulSoup (html, "html.parser")
for rn in range(0,9) :
plist = []
r = soup.find_all('tr')[rn]
# Condition: if first row, then th, otherwise td
if (rn==0) :
celltag = 'th'
else :
celltag = 'td'
# Now use the celltag instead of using fixed td or th
col = r.find_all(celltag)
print()
if col[i] == 0:
print ("")
else:
for i in range(0,4) :
cell = col[i].text
clean = cell.replace('\xa0 ', '')
clean = clean.replace (' ', '')
plist.append(clean)
# If first row, create df, otherwise add to it
if (rn == 0) :
df = pd.DataFrame(plist)
else :
df2 = pd.DataFrame(plist)
colname = 'y' + str(2019-rn)
df[colname] = df2
if (company == 1):
dft = df.T
# Get header Column
head = dft.iloc[0]
# Exclude first row from the data
dft = dft[1:]
dft.columns = head
dft = dft.reset_index()
# Assign Headers
dft = dft.drop(['index'], axis = 'columns')
else:
dft2 = df.T
# Get header Column
head = dft2.iloc[0]
# Exclude first row from the data
dft2 = dft2[1:]
dft2.columns = head
dft2 = dft2.reset_index()
# Assign Headers
dft2 = dft2.drop(['index'], axis = 'columns')
dft['Symbol'] = ThisSymbol
dft = dft.append(dft2, sort=['Year','Symbol'])
company = company +1
dft
my output looks this, i want to have a symbol column to each respective firm data
Symbol,i have added
dft['Symbol'] = ThisSymbol
but it add just first company from the list to all companies data
enter image description here

Odoo 10, Create draft invoice in website_sale after confirme sale

I want to generate a draft invoice in odoo website_sale after the confirmation of sale, so I inherit the controller, and here is the code
#http.route(['/shop/confirmation'], type='http', auth="public", website=True)
def payment_confirmation(self, **post):
sale_order_id = http.request.session.get('sale_last_order_id')
if sale_order_id:
order = http.request.env['sale.order'].sudo().browse(sale_order_id)
# here I want to create a draft invoice
return http.request.render("website_sale.confirmation", {'order': order})
else:
return http.request.redirect('/shop')
The question is : How can I create an invoice draft from the order ?
after two days I found the solution, here is my solution
#http.route(['/shop/confirmation'], type='http', auth="public", website=True)
def payment_confirmation(self, **post):
sale_order_id = http.request.session.get('sale_last_order_id')
if sale_order_id:
order = http.request.env['sale.order'].sudo().browse(sale_order_id)
for line in order.order_line:
line.qty_to_invoice = line.product_uom_qty
order.action_invoice_create()
return http.request.render("website_sale.confirmation", {'order': order})
else:
return http.request.redirect('/shop')

PySide TableView and Variant data - Display Role Not Displaying

I have this code, which when i run it in PyQt it works totally fine, but when i run it in pyside things get wierd. I get all the columns and rows im supposed to, and if i go to them via scripting and get the data, each cell says what it should. However, even though i set these as display roles, NO text shows in the table.
None in the headers, none in any of the cells. Im at a loss!
(For thos wondering, NulLVariant() just returns either None or QVariant() depending if were on pyside or pyqt)
This model is meant to take a List of Dicts to addRows, and uses dict keys to make columns.
class CustomTableModel(QtCore.QAbstractTableModel):
def __init__(self, parent=None, parentTable=None):
"""
Custom data model for holding table data.
:param parent: The parent widget/layout so that this data model gets deleted properly on close.
:param parentTable: the table that is using this data. This is used to get the font metrics of the table
display font.
"""
super(CustomTableModel, self).__init__(parent)
self.parent_table = parentTable
self.auto_resize = False
self._avg_font_w = 5
self._resize_data = defaultdict(int)
self.items = []
self.headers = []
def setParentTable(self, widget):
"""
Sets the parent table widget so that we can get its font metrics for setting our column width with autoResize.
:param widget: TableViewWidget
:raise TypeError:
"""
if not isinstance(widget, QtGui.QTableView):
raise TypeError('Must be a TableView item')
self.parent_table = widget
def setAutoResize(self, b):
"""
Turns on or off auto resize for the table. This gathers the font metrics of the parent table, and then loops
over any current data, or newly added data (including table headers) to get the widest item, and sets the
column width to fit this.
:param b: bool
:raise AttributeError:
"""
if not self.parent_table:
raise AttributeError('You must call setParentTable first to set the parent TableView item')
self.auto_resize = b
if b:
self._autoAllResizeData()
self._doColumnResize()
else:
self._resize_data = dict()
def updateSize(self):
"""
Force the table size to update to the current size data.
"""
self._doColumnResize()
def updateSizeData(self):
"""
Force an update/regathering of all the size data for each row and column.
"""
self._autoAllResizeData(True)
self._doColumnResize()
def _doColumnResize(self):
for i in range(len(self.headers)):
txt = self.headers[i]
self.parent_table.setColumnWidth(i, self._resize_data.get(txt))
def _getKeyList(self):
if self.headers:
return self.headers
elif self.items:
return sorted(self.items[0].keys())
def _getTableFontWidth(self):
self._avg_font_w = self.parent_table.fontMetrics().averageCharWidth()
def _autoAllResizeData(self, reset=False):
if not self._resize_data or reset is True:
self._resize_data = defaultdict(int)
key_list = self._getKeyList()
for header in key_list:
header_width = len(header) * (self._avg_font_w * 1.55)
if header_width > self._resize_data[header]:
self._resize_data[header] = header_width
for item in self.items:
value = item.get(header)
width = len(str(value)) * self._avg_font_w
if width > self._resize_data[header]:
self._resize_data[header] = width
def _autoSingleResizeData(self, data):
key_list = self._getKeyList()
for header in key_list:
value = data.get(header)
if value:
width = len(str(value)) * self._avg_font_w
if width > self._resize_data[header]:
self._resize_data[header] = width
def setHeaders(self, items):
"""
This allows you to set your header item text
:param items: a list of header text, ie ['Name', 'Email', 'Department']
"""
lastCount = self.columnCount(QtCore.QModelIndex())
self.headers = items
self.beginRemoveColumns(QtCore.QModelIndex(), 0, lastCount)
for x in range(lastCount):
self.removeColumn(x)
self.endRemoveColumns()
self.beginInsertColumns(QtCore.QModelIndex(), 0, len(items)-1)
self.endInsertColumns()
def addRow(self, data):
"""
Accepts a dict of data to add to the data model.
:param data: dict (this should match the same key length/names as the other data in the table.)
"""
row = len(self.items)
self.beginInsertRows(QtCore.QModelIndex(), row, row)
self.items.append(data)
self.endInsertRows()
if self.auto_resize:
self._autoSingleResizeData(data)
self._doColumnResize()
def addRows(self, data):
"""
Accepts a list of dicts to add them all to the table, with each list index being a row, and each dict key
a column.
:param data: list of dicts
:raise ValueError:
"""
if not isinstance(data, list) or not isinstance(data[0], dict):
raise ValueError('input must be a list of dicts!')
start_row = len(self.items)
end_row = len(data) + start_row - 1
self.beginInsertRows(QtCore.QModelIndex(), start_row, end_row)
self.items.extend(data)
self.endInsertRows()
if self.auto_resize:
for item in data:
self._autoSingleResizeData(item)
self._doColumnResize()
def removeRow(self, row):
"""
Remove the row at index 'row'.
:param row: int
"""
self.beginRemoveRows(QtCore.QModelIndex(), row, row)
self.items.pop(row)
self.endRemoveRows()
def clear(self):
"""
Clear all table data and start fresh.
"""
rows = self.rowCount(QtCore.QModelIndex())
self.beginRemoveRows(QtCore.QModelIndex(), 0, rows)
self.items = []
self.endRemoveRows()
cols = self.columnCount(QtCore.QModelIndex())
self.beginRemoveColumns(QtCore.QModelIndex(), 0, cols)
self.headers = []
self.endRemoveColumns()
def rowCount(self, QModelIndex):
"""
Return the row count.
:param QModelIndex:
:return:
"""
return len(self.items)
def columnCount(self, QModelIndex):
"""
Return the column count (default 1)
:param QModelIndex:
:return:
"""
try:
return len(self.items[0].keys())
except:
return 1
def data(self, index, role):
"""
Accepts a QModelIndex and a Qt.Role and returns the data at the given modelIndex.
:param index: QModelIndex
:param role: QtCore.Qt.<Role>
:return:
"""
row = index.row()
col = index.column()
if role == QtCore.Qt.DisplayRole:
key_list = self._getKeyList()
return QtCore.QVariant(str(self.items[row][key_list[col]]))
return NullVariant()
def intGetData(self, row, col):
"""
Gets the data at 'row' and 'col'.
:param row: int
:param col: int
:return: QVariant() data.
"""
try:
key_list = self._getKeyList()
return QtCore.QVariant(str(self.items[row][key_list[col]]))
except:
return NullVariant()
def headerData(self, section, orientation, role):
"""
Sets the header data based on our header key list.
:param section: section header
:param orientation: orientation
:param role: Qt<Role>
:return:
"""
if role == QtCore.Qt.DisplayRole:
if orientation == QtCore.Qt.Horizontal:
if not self.items:
if section == 0:
return QtCore.QVariant(str("Column 1"))
else:
key_list = self._getKeyList()
try:
return QtCore.QVariant(str(key_list[section]))
except:
return QtCore.QVariant('No Data')
return NullVariant()
class CustomSortModel(QtGui.QSortFilterProxyModel):
def __init__(self, parent=None):
"""
Custom QSortFilterProxyModel to allow sorting and filtering of our custom data model.
:param parent: parent so that this model is deleted properly upon close.
"""
super(CustomSortModel, self).__init__(parent)
self.countAllColumns = False
self._sortingColumn = 0
def filterAcceptsRow(self, sourceRow, sourceParent):
"""
Overriding how we choose what rows match our input filter text.
:param sourceRow: row index in question
:param sourceParent: QModelIndex
:return: bool (accepted or not)
"""
txt = ''
if self.countAllColumns:
for x in range(len(self.sourceModel().headers)):
txt += self.sourceModel().intGetData(sourceRow, x).toString()
else:
txt = self.sourceModel().intGetData(sourceRow, self._sortingColumn).toString()
if self.filterRegExp().pattern():
b = bool(re.search(str(self.filterRegExp().pattern()), str(txt)))
else:
b = bool(re.search('.*', str(txt)))
return b
def setFilterKeyColumn(self, col):
"""
Sets which column index you want the filter to apply to. -1 or less means we search all columns - otherwise,
the filter rules apply to the column index given.
:param col: signed int
:return:
"""
if col <= -1:
self.countAllColumns = True
return
self.countAllColumns = False
self._sortingColumn = col
super(CustomSortModel, self).setFilterKeyColumn(col)
Edit:
I was getting a wierd error when i tried to delete this question, but I have added a newer one, with a better cut down example for testing here:
https://stackoverflow.com/questions/34074825/pyside-qtableview-not-displaying-text-like-pyqt-does
Running your code in PySide gives a bunch of errors :
AttributeError: 'module' object has no attribute 'QVariant'
That's because there is no QVariant in PySide any more. Replacing all QVariantby regular python types fixes the code.
For example
return QtCore.QVariant('No Data')
becomes
return "No Data"

GtkTreeView filtering and selecting

I have a simple GtkTreeView and a GtkEntry used to filter the model.
When I type somehing into the entry, software_list is filtered by language.
software_list = [("Firefox", 2002, "C++"),
("Eclipse", 2004, "Java" ),
("Netbeans", 1996, "Java"),
("Chrome", 2008, "C++"),
("GCC", 1987, "C"),
("Frostwire", 2004, "Java")]
class TreeViewFilterWindow(Gtk.Window):
def __init__(self):
Gtk.Window.__init__(self)
self.curr_filter = ''
self.entry = Gtk.Entry()
self.entry.connect('changed', self.on_text_change)
self.software_liststore = Gtk.ListStore(str, int, str)
for software_ref in software_list:
self.software_liststore.append(list(software_ref))
self.filter = self.software_liststore.filter_new()
self.filter.set_visible_func(self.filter_func)
self.treeview = Gtk.TreeView.new_with_model(self.filter)
for i, column_title in enumerate(["Software", "Release Year", "Programming Language"]):
renderer = Gtk.CellRendererText()
column = Gtk.TreeViewColumn(column_title, renderer, text=i)
self.treeview.append_column(column)
self.treeview.get_selection().connect('changed', self.on_row_select)
# packing into boxes, showing components, starting main loop goes here
def on_text_change(self, entry):
self.curr_filter = entry.get_text()
self.filter.refilter()
def filter_func(self, model, iter, data):
if self.curr_filter:
return re.search(re.escape(self.curr_filter), model[iter][2])
else:
return True
The problem is, when I select i.e. "Chrome" from the list and then type "Java" into the entry, then, obviously, "Chrome" gets hidden but selection changes to some other, random row. I'd prefer TreeView unselected hidden elements instead of changing the selection. How can I do this?
This just works as expected in Gtk2, but in Gtk3 you need to deselect the row if it disappears. The appropriate code is
class TreeViewFilterWindow(Gtk.Window):
def __init__(...):
...
self.selection = self.treeview.get_selection()
self.filter.connect('row-deleted', self.on_row_deleted)
def on_row_deleted(self, model, path):
if self.selection.path_is_selected(path):
GObject.idle_add(self.selection.unselect_path, path)
I found that calling self.selection.unselect_path(path) directly didn't seem to work for some reason, but deferring it with idle_add sorted it out.

Resources