Fix get payment_term

This commit is contained in:
Oscar Alvarez 2020-06-19 10:28:55 -05:00
parent 4659847b00
commit 74120560c5
2 changed files with 6 additions and 465 deletions

View File

@ -1,459 +0,0 @@
import os
from operator import itemgetter
from datetime import timedelta
from PyQt5.QtCore import Qt, QVariant, QAbstractTableModel, \
pyqtSignal, QModelIndex, QSize
from PyQt5.QtWidgets import QTableView, QVBoxLayout, \
QAbstractItemView, QLineEdit, QDialog, QLabel, QScroller, \
QHBoxLayout, QScrollArea, QItemDelegate
from PyQt5.QtGui import QPixmap, QIcon
from neox.commons.buttons import ActionButton
__all__ = ['Item', 'SearchWindow', 'TableModel']
DELTA_LOCALE = -5 # deltatime col
DIR = os.path.abspath(os.path.normpath(os.path.join(__file__,
'..', '..')))
ICONS = {
'image': os.path.join(DIR, 'share/icon-camera.svg'),
'stock': os.path.join(DIR, 'share/icon-stock.svg'),
}
class Item(QItemDelegate):
def __init__(self, values, fields):
super(Item, self).__init__()
_ = [setattr(self, n, str(v)) for n, v in zip(fields, values)]
class SearchWindow(QDialog):
def __init__(self, parent, headers, records, methods, filter_column=[],
cols_width=[], title=None, fill=False):
"""
parent: parent window
headers: is a ordered dict of data with name field-column as keys.
records: is a tuple with two values: a key called 'objects' or 'values',
and a list of instances values or plain values for build data model:
[('a' 'b', 'c'), ('d', 'e', 'f')...]
on_selected_method: method to call when triggered the selection
filter_column: list of column to search values, eg: [0,2]
title: title of window
cols_width: list of width of columns, eg. [120, 60, 280]
fill: Boolean that define if the table must be fill with all data and
values and these are visibles
"""
super(SearchWindow, self).__init__(parent)
self.parent = parent
self.headers = headers
self.records = records
self.fill = fill
self.methods = methods
self.on_selected_method = methods.get('on_selected_method')
self.on_return_method = methods.get('on_return_method')
self.filter_column = filter_column
self.cols_width = cols_width
self.rows = []
self.current_row = None
if not title:
title = self.tr('SEARCH...')
self.setWindowTitle(title)
WIDTH = 550
if cols_width:
WIDTH = sum(cols_width) + 130
self.resize(QSize(WIDTH, 400))
self.create_table()
self.create_widgets()
self.create_layout()
self.create_connections()
if records:
if records[0] == 'objects':
self.set_from_objects(records[1])
elif records[0] == 'values':
self.set_from_values(records[1])
elif records[0] == 'data':
self.set_from_data(records[1])
def get_id(self):
if self.current_row:
return self.current_row['id']
def clear_rows(self):
if self.fill:
self.table_model.items = []
self.table_model.currentItems = []
self.table_model.layoutChanged.emit()
def clear_filter(self):
self.filter_field.setText('')
self.filter_field.setFocus()
if self.fill:
self.table_model.items = []
self.table_view.selectRow(-1)
self.table_model.currentItems = []
self.table_model.layoutChanged.emit()
def set_from_data(self, values):
if self.fill:
self.clear_filter()
self.table_model.set_rows(values, typedata='list')
def set_from_values(self, values):
if self.fill:
self.clear_rows()
self.table_model.set_rows(values)
self.update_count_field()
def update_count_field(self):
values = self.table_model.currentItems
self.label_count.setText(str(len(values)))
def activate_counter(self):
self.label_control = QLabel('0')
self.label_control.setObjectName('label_count')
self.label_control.setAlignment(Qt.AlignCenter | Qt.AlignVCenter)
self.filter_layout.addWidget(self.label_control)
def set_counter_control(self, val):
self.label_control.setText(str(len(val)))
def set_from_objects(self, objects):
self.rows = []
for object_ in objects:
row = []
for field, data in self.headers.items():
val = getattr(object_, field)
if hasattr(val, 'name'):
val = getattr(val, 'name')
elif data['type'] == 'number':
val = val
elif data['type'] == 'int':
val = str(val)
elif data['type'] == 'date':
val = val.strftime('%d/%m/%Y')
row.append(val)
self.rows.append(row)
self.table_model.set_rows(self.rows)
def create_table(self):
# set the table model
self.table_model = TableModel(self, self.rows, self.headers,
self.filter_column, fill=self.fill)
self.table_view = QTableView()
self.table_view.setModel(self.table_model)
self.table_view.setMinimumSize(450, 350)
self.table_view.setColumnHidden(0, True)
self.table_view.setAlternatingRowColors(True)
self.table_view.setSelectionBehavior(QAbstractItemView.SelectRows)
self.table_view.setGridStyle(Qt.DotLine)
for i in range(len(self.cols_width)):
self.table_view.setColumnWidth(i, self.cols_width[i])
vh = self.table_view.verticalHeader()
vh.setVisible(False)
hh = self.table_view.horizontalHeader()
hh.setStretchLastSection(True)
# enable sorting
self.table_view.setSortingEnabled(True)
def create_widgets(self):
self.filter_label = QLabel(self.tr("FILTER:"))
self.filter_field = QLineEdit()
self.label_count = QLabel('0')
self.label_count.setObjectName('label_count')
self.label_count.setAlignment(Qt.AlignCenter | Qt.AlignVCenter)
self.pushButtonOk = ActionButton('ok', self.action_selection_changed)
self.pushButtonCancel = ActionButton('cancel', self.action_close)
def create_layout(self):
layout = QVBoxLayout()
self.filter_layout = QHBoxLayout()
self.filter_layout.addWidget(self.filter_label)
self.filter_layout.addWidget(self.filter_field)
self.filter_layout.addWidget(self.label_count)
layout.addLayout(self.filter_layout)
scroll_area = QScrollArea()
scroll_area.setWidgetResizable(True)
scroll_area.setVerticalScrollBarPolicy(Qt.ScrollBarAlwaysOn)
scroll_area.setWidget(self.table_view)
layout.addWidget(scroll_area)
buttons_layout = QHBoxLayout()
buttons_layout.addWidget(self.pushButtonCancel)
buttons_layout.addWidget(self.pushButtonOk)
layout.addLayout(buttons_layout)
QScroller.grabGesture(scroll_area, QScroller.LeftMouseButtonGesture)
self.filter_field.setFocus()
self.setLayout(layout)
def create_connections(self):
self.filter_field.textChanged.connect(self.action_text_changed)
self.filter_field.returnPressed.connect(self.action_filter_return_pressed)
self.table_view.clicked.connect(self.action_selection_changed)
self.table_view.activated.connect(self.action_table_activated)
def action_table_activated(self):
pass
def execute(self):
self.current_row = None
self.parent.releaseKeyboard()
self.filter_field.setFocus()
return self.exec_()
def show(self):
self.parent.releaseKeyboard()
self.clear_filter()
self.filter_field.setFocus()
super(SearchWindow, self).show()
def hide(self):
self.parent.grabKeyboard()
self.parent.setFocus()
super(SearchWindow, self).hide()
def action_close(self):
self.close()
def action_selection_changed(self):
selected = self.table_view.currentIndex()
# current_row is a dict with values used on mainwindow
self.current_row = self.table_model.getCurrentRow(selected)
if selected.row() < 0:
self.filter_field.setFocus()
else:
column = selected.column()
name_field = self.table_model.header_fields[column]
if self.methods.get(name_field):
parent_method = self.methods[name_field]
parent_method()
return
self.hide()
if self.parent:
getattr(self.parent, self.on_selected_method)()
self.filter_field.setText('')
def action_text_changed(self):
self.table_model.setFilter(searchText=self.filter_field.text())
self.update_count_field()
self.table_model.layoutChanged.emit()
def action_filter_return_pressed(self):
if hasattr(self.parent, self.on_return_method):
method = getattr(self.parent, self.on_return_method)
method()
def keyPressEvent(self, event):
key = event.key()
selected = self.table_view.currentIndex()
if key == Qt.Key_Down:
if not self.table_view.hasFocus():
self.table_view.setFocus()
self.table_view.selectRow(selected.row() + 1)
elif key == Qt.Key_Up:
if selected.row() == 0:
self.filter_field.setFocus()
else:
self.table_view.selectRow(selected.row() - 1)
elif key == Qt.Key_Return:
if selected.row() < 0:
self.filter_field.setFocus()
else:
self.action_selection_changed()
elif key == Qt.Key_Escape:
self.hide()
else:
pass
super(SearchWindow, self).keyPressEvent(event)
class TableModel(QAbstractTableModel):
sigItem_selected = pyqtSignal(str)
def __init__(self, parent, rows, headers, filter_column=[], fill=False, *args):
"""
rows: a list of dicts with values
headers: a list of strings
filter_column: list of index of columns for use as filter
fill: If is True ever the rows will be visible
"""
QAbstractTableModel.__init__(self, parent, *args)
self.rows = rows
self.fill = fill
self.headers = headers
self.header_fields = [h for h in headers.keys()]
self.header_name = [h['desc'] for h in headers.values()]
self.rows = []
self.currentItems = []
self.items = []
self.searchField = None
self.mainColumn = 2
self.filter_column = filter_column
self.create_icons()
if rows and fill:
self.set_rows(rows)
def create_icons(self):
pix_camera = QPixmap()
pix_camera.load(ICONS['image'])
icon_camera = QIcon()
icon_camera.addPixmap(pix_camera)
pix_stock = QPixmap()
pix_stock.load(ICONS['stock'])
icon_stock = QIcon()
icon_stock.addPixmap(pix_stock)
self.icons = {
'icon_image': icon_camera,
'icon_stock': icon_stock,
}
def _get_item(self, values):
res = {}
for name, data in self.headers.items():
if '.' in name:
attrs = name.split('.')
val = values.get(attrs[0])
if val:
val = val.get(attrs[1])
else:
val = values[name]
if val:
if data['type'] == 'date':
val = val.strftime('%d-%m-%Y')
elif data['type'] == 'number':
val = '{0:,}'.format(val)
elif data['type'] == 'datetime':
mod_hours = val + timedelta(hours=DELTA_LOCALE)
val = mod_hours.strftime('%d/%m/%Y %I:%M %p')
elif data['type'] == 'icon':
val = self.icons['icon_' + data['icon']]
res[name] = val
return res
def set_rows(self, rows):
self.beginResetModel()
self.endResetModel()
self.rows = rows
for values in rows:
self.insertRows(self._get_item(values))
if self.fill is True:
self.currentItems = self.items
def set_rows_list(self, rows):
self.beginResetModel()
self.endResetModel()
for values in rows:
self.insertRows(Item(values, self.header_fields))
if self.fill is True:
self.currentItems = self.items
def rowCount(self, parent):
return len(self.rows)
def columnCount(self, parent):
return len(self.header_fields)
def getCurrentRow(self, index):
row = index.row()
if self.currentItems and row >= 0 and len(self.currentItems) > row:
return self.currentItems[row]
def data(self, index, role, col=None):
if not index.isValid():
return
row = index.row()
if col is None:
column = index.column()
else:
column = col
item = None
if self.currentItems and len(self.currentItems) > row:
item = self.currentItems[row]
name_field = self.header_fields[column]
data = self.headers[name_field]
if role == Qt.DisplayRole and item:
if column is not None:
return item.get(name_field)
elif role == Qt.DecorationRole:
if item:
return item[name_field]
elif role == Qt.TextAlignmentRole:
if item:
align = Qt.AlignmentFlag(Qt.AlignLeft)
if data['type'] == 'icon':
align = Qt.AlignmentFlag(Qt.AlignHCenter)
elif data['type'] == 'number':
align = Qt.AlignmentFlag(Qt.AlignRight)
return align
elif role == Qt.UserRole:
return item
def headerData(self, col, orientation, role):
if orientation == Qt.Horizontal and role == Qt.DisplayRole:
return QVariant(self.header_name[col])
return QVariant()
def insertRows(self, item, row=0, column=1, index=QModelIndex()):
self.beginInsertRows(index, row, row + 1)
self.items.append(item)
self.endInsertRows()
def sort(self, column, order):
name_field = self.header_fields[column]
if 'icon-' in name_field:
return
data = [(value[name_field], value) for value in self.items]
data.sort(key=itemgetter(0), reverse=order)
self.currentItems = [v for k, v in data]
self.layoutChanged.emit()
def setFilter(self, searchText=None, mainColumn=None, order=None):
if not searchText:
return
if mainColumn is not None:
self.mainColumn = mainColumn
self.order = order
self.currentItems = self.items
if searchText and self.filter_column:
matchers = [t.lower() for t in searchText.split(' ')]
self.filteredItems = []
for item in self.currentItems:
values_clear = list(filter(None, item.values()))
exists = all(mt in ''.join(values_clear).lower() for mt in matchers)
if exists:
self.filteredItems.append(item)
self.currentItems = self.filteredItems
self.layoutChanged.emit()
def clear_filter(self):
if self.fill:
self.items = []
self.currentItems = []
self.layoutChanged.emit()

View File

@ -1416,16 +1416,16 @@ class MainWindow(FrontWindow):
'shipment_address': party['addresses'][0]['id'],
}
if party.get('customer_payment_term'):
values['payment_term'] = party.get('customer_payment_term')
self.field_payment_term.setText(str(party['customer_payment_term']['name']))
self.field_payment_term_id = party.get('customer_payment_term')
payment_term = party.get('customer_payment_term')
if payment_term:
values['payment_term'] = payment_term['id']
self.field_payment_term.setText(str(payment_term['name']))
self.field_payment_term_id = payment_term['id']
else:
values['payment_term'] = self.default_payment_term['id']
self.field_payment_term_id = self.default_payment_term['id']
self.field_payment_term.setText(self.default_payment_term['name'])
print(self._sale['id'], values)
values['payment_term'] = values['payment_term']['id']
self._PosSale.write([self._sale['id']], values)
self.party_id = party_id