presik_pos/app/commons/model.py

217 lines
6.8 KiB
Python

from PyQt5.QtCore import Qt, QAbstractTableModel, QModelIndex
import math
__all__ = ['TableModel', 'TableEdit']
class TableEdit(QAbstractTableModel):
def __init__(self, parent, data, fields):
super(TableEdit, self).__init__()
self._data = data
self._parent = parent
self._fields = fields
def data(self, index, role):
if role == Qt.DisplayRole:
row = index.row()
col = index.column()
val = self._data[row][col]
if self._fields[col]['type'] == 'integer':
return int(val)
return val
def rowCount(self, index):
return len(self._data)
def columnCount(self, index):
return len(self._fields) if self._fields else 0
def clearData(self):
self.beginRemoveRows(QModelIndex(), 0, len(self._data))
self._data = []
self.endRemoveRows()
self.layoutChanged.emit()
def get_data(self, index):
raw_value = self._data[index.row()]
return raw_value
def setData(self, index, value, role):
if role == Qt.EditRole:
if not value:
return False
row = index.row()
col = index.column()
if self._fields[col]['type'] == 'integer':
value = int(value)
self._data[row][col] = value
on_change = self._fields[col].get('change')
if on_change:
method = getattr(self._parent, on_change)
method(row)
return True
def flags(self, index):
col = index.column()
if self._fields[col].get('readonly'):
return Qt.ItemIsEnabled
else:
return Qt.ItemIsEnabled | Qt.ItemIsSelectable | Qt.ItemIsEditable
def headerData(self, section, orientation, role):
""" Set the headers to be displayed. """
if role != Qt.DisplayRole:
return None
if orientation == Qt.Horizontal:
for i in range(len(self._fields)):
if section == i:
return self._fields[i]['label']
return None
def add_record(self, rec):
length = len(self._data)
self.beginInsertRows(QModelIndex(), length, length)
self._data.append(rec)
self.endInsertRows()
return rec
def get_sum(self, col):
return sum([int(d[col]) for d in self._data])
class TableModel(QAbstractTableModel):
def __init__(self, model, fields):
super(TableModel, self).__init__()
self._fields = fields
self.model = model
self._data = []
def reset(self):
self.beginResetModel()
self._data = []
self.endResetModel()
def add_record(self, rec):
length = len(self._data)
self.beginInsertRows(QModelIndex(), length, length)
self._data.append(rec)
self.endInsertRows()
return rec
def get_id(self):
pass
def removeId(self, row, mdl_idx):
self.beginRemoveRows(mdl_idx, row, row)
id_ = self._data[row].get('id')
self._data.pop(row)
self.endRemoveRows()
return id_
def deleteRecords(self, ids):
pass
def rowCount(self, parent=None):
return len(self._data)
def columnCount(self, parent=None):
return len(self._fields) if self._fields else 0
def get_data(self, index):
raw_value = self._data[index.row()]
return raw_value
def get_value(self, data, field):
value = ''
list_ = field.split('.')
for l in list_:
if not data.get(l):
return None
value = data[l]
data = data[l]
return value
def data(self, index, role, field_name='name'):
field = self._fields[index.column()]
if role == Qt.DisplayRole:
index_row = self._data[index.row()]
raw_value = ''
if not index_row.get(field.get(field_name)):
if '.' in field.get(field_name):
raw_value = self.get_value(index_row, field[field_name])
else:
raw_value = index_row[field[field_name]]
digits = None
if field.get('digits'):
digits = 0
target_field = field.get('digits')[0]
target = None
try:
if index_row.get(target_field):
target = index_row[target_field]
elif '.' in target_field:
split_ = target_field.split('.')
target = index_row[split_[0]][split_[1]]
except:
pass
# if index_row.get(target_field):
# target = index_row[target_field]
if target:
group_digits = field.get('digits')[1]
if group_digits.get(target):
digits = group_digits.get(target)
eval_value = math.floor(float(raw_value)) - float(raw_value)
if target == 'u' and (eval_value > 0 or eval_value < 0):
digits = 2
if raw_value is None:
raw_value = ''
fmt_value = raw_value
if raw_value and field.get('format'):
field_format = field['format']
if digits or digits == 0:
field_format = field['format'] % str(digits)
if isinstance(raw_value, str) and raw_value != '':
raw_value = float(raw_value)
if field_format == '{:,d}':
raw_value = int(raw_value)
if raw_value:
fmt_value = field_format.format(raw_value)
return fmt_value
elif role == Qt.TextAlignmentRole:
align = Qt.AlignmentFlag(Qt.AlignVCenter | field['align'])
return align
else:
return None
def get_sum(self, field_target):
res = sum([d[field_target] for d in self._data])
return res
def update_record(self, rec, pos=None):
if pos is None:
pos = 0
for d in self._data:
if d['id'] == rec['id']:
break
pos += 1
self._data.pop(pos)
self._data.insert(pos, rec)
start_pos = self.index(pos, 0)
end_pos = self.index(pos, len(self._fields) - 1)
self.dataChanged.emit(start_pos, end_pos)
return rec
def headerData(self, section, orientation, role):
""" Set the headers to be displayed. """
if role != Qt.DisplayRole:
return None
elements = [f['description'] for f in self._fields]
if orientation == Qt.Horizontal:
for i in range(len(elements)):
if section == i:
return elements[i]
return None