mirror of
https://bitbucket.org/presik/presik_pos.git
synced 2023-12-14 06:03:00 +01:00
345 lines
10 KiB
Python
345 lines
10 KiB
Python
import locale
|
|
|
|
from PyQt5.QtWidgets import (QLineEdit, QLabel, QComboBox,
|
|
QGridLayout, QTextEdit, QTreeView, QCompleter)
|
|
from PyQt5.QtCore import Qt, QRegExp
|
|
from PyQt5.QtGui import QRegExpValidator, QDoubleValidator
|
|
|
|
from .qt_models import get_simple_model
|
|
from .model import Modules
|
|
|
|
regex_ = QRegExp("^\\d{1,3}(([.]\\d{3})*),(\\d{2})$")
|
|
validator = QRegExpValidator(regex_)
|
|
|
|
try:
|
|
locale.setlocale(locale.LC_ALL, str('es_CO.UTF-8'))
|
|
except:
|
|
print("Warning: Error setting locale")
|
|
|
|
__all__ = ['Label', 'Field', 'ComboBox', 'GridForm', 'FieldMoney']
|
|
|
|
|
|
def set_object_name(obj, type_, value):
|
|
size = 'small'
|
|
color = 'gray'
|
|
if value.get('size'):
|
|
size = value.get('size')
|
|
if value.get('color'):
|
|
color = value.get('color')
|
|
name = type_ + size + '_' + color
|
|
obj.setObjectName(name)
|
|
|
|
|
|
class Completer(QCompleter):
|
|
|
|
def __init__(self, parent, records, fields):
|
|
super(Completer, self).__init__()
|
|
|
|
self.parent = parent
|
|
self.treeview_search = QTreeView()
|
|
col_headers = self.treeview_search.header()
|
|
col_headers.hide()
|
|
self.setPopup(self.treeview_search)
|
|
self.fields = fields
|
|
self._set_model(records, fields)
|
|
self.activated.connect(self.on_accept)
|
|
self.setFilterMode(Qt.MatchContains)
|
|
self.setCaseSensitivity(Qt.CaseInsensitive)
|
|
self.setWrapAround(True)
|
|
self.setCompletionColumn(1)
|
|
|
|
self.treeview_search.setColumnWidth(1, 300)
|
|
self.treeview_search.setColumnHidden(0, True)
|
|
self.id = None
|
|
|
|
def get_values(self, records):
|
|
vkeys = [f[0] for f in self.fields]
|
|
values = []
|
|
for r in records:
|
|
row = []
|
|
for key in vkeys:
|
|
if '.' in key:
|
|
attrs = key.split('.')
|
|
val = r.copy()
|
|
for a in attrs:
|
|
val = val[a]
|
|
else:
|
|
val = r[key]
|
|
row.append(val)
|
|
values.append(row)
|
|
return values
|
|
|
|
def _set_model(self, records, headers):
|
|
headers = [f[1] for f in self.fields]
|
|
values = self.get_values(records)
|
|
self.model = get_simple_model(self.parent, values, headers)
|
|
self.setModel(self.model)
|
|
|
|
def on_accept(self):
|
|
model_index = self._get_model_index()
|
|
idx = self.model.index(model_index.row(), 0)
|
|
self.id = idx.data()
|
|
|
|
def _get_model_index(self):
|
|
item_view = self.popup()
|
|
index = item_view.currentIndex()
|
|
proxy_model = self.completionModel()
|
|
model_index = proxy_model.mapToSource(index)
|
|
return model_index
|
|
|
|
|
|
class Label(QLabel):
|
|
|
|
def __init__(self, obj, key, value, align='right'):
|
|
super(Label, self).__init__()
|
|
self.setText(value['name'] + ':')
|
|
set_object_name(self, 'label_', value)
|
|
if align == 'left':
|
|
self.setAlignment(Qt.AlignLeft | Qt.AlignVCenter)
|
|
else:
|
|
self.setAlignment(Qt.AlignRight | Qt.AlignVCenter)
|
|
|
|
|
|
class Field(QLineEdit):
|
|
|
|
def __init__(self, obj, key, value, type=None):
|
|
super(Field, self).__init__()
|
|
setattr(obj, 'field_' + key, self)
|
|
self.parent = obj
|
|
set_object_name(self, 'field_', value)
|
|
if value.get('type') == 'numeric':
|
|
self.setAlignment(Qt.AlignRight | Qt.AlignVCenter)
|
|
elif value.get('type') == 'relation':
|
|
self.set_completer(value.get('model'), value.get('fields'),
|
|
value.get('domain'))
|
|
|
|
def set_completer(self, model, fields, domain=[]):
|
|
records = model.find(domain)
|
|
self.completer = Completer(self.parent, records, fields)
|
|
self.setCompleter(self.completer)
|
|
|
|
def get_id(self):
|
|
return self.completer.id
|
|
|
|
# FIXME
|
|
def _get_tryton_model(self, model, fields):
|
|
modules = Modules(self, self.conn)
|
|
modules.set_models([ {
|
|
'name': '_Model',
|
|
'model': model,
|
|
'fields': fields,
|
|
}])
|
|
|
|
|
|
class TextField(QTextEdit):
|
|
|
|
def __init__(self, obj, key, value):
|
|
super(Field, self).__init__()
|
|
setattr(obj, 'field_' + key, self)
|
|
set_object_name(self, 'field_', value)
|
|
self.value_changed = False
|
|
self.setValidator(validator)
|
|
|
|
def textChanged(self, text):
|
|
self.value_changed = True
|
|
|
|
|
|
class FieldMoney(QLineEdit):
|
|
|
|
def __init__(self, obj, key, value, amount=None, digits=2, readonly=True):
|
|
super(FieldMoney, self).__init__()
|
|
setattr(obj, 'field_' + key, self)
|
|
set_object_name(self, 'field_', value)
|
|
self.setAlignment(Qt.AlignRight | Qt.AlignVCenter)
|
|
self.digits = 2
|
|
self.value_changed = False
|
|
self.textEdited.connect(self.value_edited)
|
|
self._text = '0'
|
|
self.amount = 0
|
|
self.setReadOnly(readonly)
|
|
validator = QDoubleValidator()
|
|
validator.setDecimals(2)
|
|
self.setValidator(validator)
|
|
if not amount:
|
|
self.zero()
|
|
|
|
def __str__(self):
|
|
return self.format_text()
|
|
|
|
def format_text(self, text_):
|
|
amount = float(text_)
|
|
return "{:,}".format(round(amount, self.digits))
|
|
|
|
def setText(self, amount):
|
|
if not amount:
|
|
text = ''
|
|
else:
|
|
text = self.format_text(amount)
|
|
# text = amount
|
|
super(FieldMoney, self).setText(str(text))
|
|
|
|
def zero(self):
|
|
self.setText(str(0))
|
|
|
|
def value_edited(self, amount):
|
|
self.value_changed = True
|
|
|
|
def show(self):
|
|
pass
|
|
|
|
|
|
class FieldNumeric(QLineEdit):
|
|
|
|
def __init__(self, obj, key, value, amount=None, digits=2, readonly=True):
|
|
super(FieldNumeric, self).__init__()
|
|
setattr(obj, 'field_' + key, self)
|
|
set_object_name(self, 'field_', value)
|
|
self.setAlignment(Qt.AlignRight | Qt.AlignVCenter)
|
|
self.digits = 2
|
|
self.value_changed = False
|
|
self.textEdited.connect(self.value_edited)
|
|
self._text = '0'
|
|
self.amount = 0
|
|
self.setReadOnly(readonly)
|
|
validator = QDoubleValidator()
|
|
validator.setDecimals(2)
|
|
self.setValidator(validator)
|
|
if not amount:
|
|
self.zero()
|
|
|
|
def __str__(self):
|
|
return self.format_text()
|
|
|
|
# def format_text(self, text_):
|
|
# amount = float(text_)
|
|
# return "{:,}".format(round(amount, self.digits))
|
|
|
|
def setText(self, amount):
|
|
if not amount:
|
|
text = ''
|
|
else:
|
|
text = amount
|
|
text = str(text).lstrip('0')
|
|
super(FieldNumeric, self).setText(text)
|
|
|
|
def zero(self):
|
|
self.setText(str(0))
|
|
|
|
def value_edited(self, amount):
|
|
self.value_changed = True
|
|
|
|
def show(self):
|
|
pass
|
|
|
|
|
|
class ComboBox(QComboBox):
|
|
|
|
def __init__(self, obj, key, data):
|
|
super(ComboBox, self).__init__()
|
|
setattr(obj, 'field_' + key, self)
|
|
self.parent = obj
|
|
self.setFrame(True)
|
|
self.setObjectName('field_' + key)
|
|
values = []
|
|
if data.get('values'):
|
|
values = data.get('values')
|
|
heads = []
|
|
if data.get('heads'):
|
|
heads = data.get('heads')
|
|
selection_model = get_simple_model(obj, values, heads)
|
|
self.setModel(selection_model)
|
|
self.setModelColumn(1)
|
|
selection_model.findItems(str(3), column=0)
|
|
if data.get('on_change'):
|
|
self.method_on_change = getattr(self.parent, data.get('on_change'))
|
|
self.currentIndexChanged.connect(self.on_change)
|
|
|
|
def on_change(self, index):
|
|
self.method_on_change(index)
|
|
|
|
def set_editable(self, value=True):
|
|
self.setEditable(value)
|
|
|
|
def set_enabled(self, value=True):
|
|
self.setEnabled(value)
|
|
|
|
def get_id(self):
|
|
model = self.model()
|
|
row = self.currentIndex()
|
|
column = 0 # id ever is column Zero
|
|
res = model.item(row, column)
|
|
return res.text()
|
|
|
|
def get_label(self):
|
|
model = self.model()
|
|
row = self.currentIndex()
|
|
column = 1 # id ever is column Zero
|
|
res = model.item(row, column)
|
|
return res.text()
|
|
|
|
def set_from_id(self, id_):
|
|
model = self.model()
|
|
items = model.findItems(str(id_), column=0)
|
|
idx = model.indexFromItem(items[0])
|
|
self.setCurrentIndex(idx.row())
|
|
|
|
|
|
class GridForm(QGridLayout):
|
|
"""
|
|
Add a simple form Grid Style to screen,
|
|
from a data dict with set of {values, attributes}
|
|
example:
|
|
(field_name, {
|
|
'name': string descriptor,
|
|
'readonly': Bool,
|
|
'type': type_widget,
|
|
'placeholder': True or False,
|
|
}),
|
|
col:: is number of columns
|
|
type_widget :: field or selection
|
|
"""
|
|
|
|
def __init__(self, obj, values, col=1):
|
|
super(GridForm, self).__init__()
|
|
row = 1
|
|
cols = 0
|
|
align = 'right'
|
|
if col == 0:
|
|
align = 'left'
|
|
|
|
for key, value in values.items():
|
|
if not value.get('placeholder'):
|
|
_label = Label(obj, key, value, align)
|
|
if value.get('type') == 'selection':
|
|
_field = ComboBox(obj, key, value)
|
|
elif value.get('type') == 'money':
|
|
_field = FieldMoney(obj, key, value)
|
|
else:
|
|
_field = Field(obj, key, value)
|
|
if value.get('password') is True:
|
|
_field.setEchoMode(QLineEdit.Password)
|
|
if value.get('placeholder'):
|
|
_field.setPlaceholderText(value['name'])
|
|
|
|
self.setRowStretch(row, 0)
|
|
column1 = cols * col + 1
|
|
column2 = column1 + 1
|
|
if value.get('invisible') is True:
|
|
continue
|
|
if not value.get('placeholder'):
|
|
self.addWidget(_label, row, column1)
|
|
if col == 0:
|
|
row = row + 1
|
|
self.addWidget(_field, row, column1)
|
|
else:
|
|
self.addWidget(_field, row, column2)
|
|
|
|
if value.get('readonly') is True:
|
|
_field.setReadOnly(True)
|
|
_field.setFocusPolicy(Qt.NoFocus)
|
|
|
|
if cols < (col - 1):
|
|
cols += 1
|
|
else:
|
|
row += 1
|
|
cols = 0
|