mirror of
https://bitbucket.org/presik/presik_pos.git
synced 2023-12-14 06:03:00 +01:00
change new version
This commit is contained in:
parent
3c6c0e3027
commit
e55a11fb18
12 changed files with 1016 additions and 747 deletions
|
@ -97,7 +97,7 @@ class ButtonsStacked(QHBoxLayout):
|
|||
id='button_accept',
|
||||
parent=parent,
|
||||
icon=get_icon('accept'),
|
||||
title='FINALIZE',
|
||||
title=self.tr('FINISH'),
|
||||
name_style='toolbar',
|
||||
method='button_accept_pressed'
|
||||
)
|
||||
|
@ -105,7 +105,7 @@ class ButtonsStacked(QHBoxLayout):
|
|||
id='button_cash',
|
||||
parent=parent,
|
||||
icon=get_icon('cash'),
|
||||
title='PAY',
|
||||
title=self.tr('PAY'),
|
||||
name_style='toolbar',
|
||||
method='button_cash_pressed'
|
||||
)
|
||||
|
@ -119,7 +119,7 @@ class ButtonsStacked(QHBoxLayout):
|
|||
self.button_to_draft = CustomButton(
|
||||
id='button_to_draft',
|
||||
parent=parent,
|
||||
title='RETURN TO SALESMAN',
|
||||
title=self.tr('RETURN TO DRAFT'),
|
||||
icon=get_icon('draft'),
|
||||
name_style='toolbar',
|
||||
method='button_to_draft_pressed'
|
||||
|
@ -140,7 +140,7 @@ class ButtonsStacked(QHBoxLayout):
|
|||
id='button_send_to_pay',
|
||||
icon=get_icon('draft'),
|
||||
parent=parent,
|
||||
title='SEND TO PAY',
|
||||
title=self.tr('GO TO PAY'),
|
||||
method='button_send_to_pay_pressed',
|
||||
name_style='toolbar'
|
||||
)
|
||||
|
|
|
@ -188,6 +188,50 @@ class FieldMoney(QLineEdit):
|
|||
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 = self.format_text(amount)
|
||||
text = amount
|
||||
super(FieldNumeric, 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 ComboBox(QComboBox):
|
||||
|
||||
def __init__(self, obj, key, data):
|
||||
|
|
|
@ -4,6 +4,10 @@
|
|||
background-color: #424242;
|
||||
}
|
||||
|
||||
#label_input {
|
||||
color : #424242;
|
||||
}
|
||||
|
||||
QListView {
|
||||
font: bold 46px;
|
||||
color: #424242;
|
||||
|
|
660
app/dialogs.py
660
app/dialogs.py
|
@ -1,87 +1,94 @@
|
|||
|
||||
from .commons.dialogs import HelpDialog, QuickDialog
|
||||
from PyQt5.QtCore import Qt, QThread, pyqtSignal, QRect, QDate
|
||||
from PyQt5.QtWidgets import (QLabel, QTextEdit, QHBoxLayout, QVBoxLayout,
|
||||
QWidget, QGridLayout, QLineEdit, QDoubleSpinBox, QDateEdit)
|
||||
from .constants import (PATH_PRINTERS, DELTA_LOCALE, STRETCH, alignRight,
|
||||
alignLeft, alignCenter, alignHCenter, alignVCenter, DIALOG_REPLY_NO,
|
||||
DIALOG_REPLY_YES, ZERO, FRACTIONS, RATE_CREDIT_LIMIT, SCREENS, FILE_BANNER,
|
||||
CONVERSION_DIGITS)
|
||||
from .commons.forms import GridForm, FieldMoney, ComboBox
|
||||
from PyQt5.QtCore import QRect
|
||||
from PyQt5.QtWidgets import (QWidget, QLabel, QTextEdit, QVBoxLayout,
|
||||
QGridLayout, QLineEdit, QDoubleSpinBox, QDateEdit)
|
||||
from .constants import (alignCenter, FRACTIONS)
|
||||
from .commons.forms import FieldMoney, ComboBox
|
||||
from .commons.search_window import SearchWindow
|
||||
from collections import OrderedDict
|
||||
from .manage_tables import ManageTables
|
||||
from decimal import Decimal
|
||||
from .tools import get_icon, to_float, to_numeric
|
||||
|
||||
|
||||
class SearchSale(SearchWindow):
|
||||
class SearchSale(QWidget):
|
||||
def __init__(self, parent):
|
||||
super(SearchSale, self).__init__(parent)
|
||||
self._parent = parent
|
||||
|
||||
def get(self):
|
||||
headers = OrderedDict()
|
||||
headers['id'] = {'desc': parent.tr('ID'), 'type': 'char'}
|
||||
headers['number'] = {'desc': parent.tr('NUMBER'), 'type': 'char'}
|
||||
headers['invoice_number'] = {'desc': parent.tr('INVOICE'), 'type': 'char'}
|
||||
headers['party.name'] = {'desc': parent.tr('PARTY'), 'type': 'char'}
|
||||
headers['sale_date'] = {'desc': parent.tr('DATE'), 'type': 'char'}
|
||||
headers['salesman.name'] = {'desc': parent.tr('SALESMAN'), 'type': 'char'}
|
||||
headers['position'] = {'desc': parent.tr('POSITION'), 'type': 'char'}
|
||||
headers['total_amount_cache'] = {'desc': parent.tr('TOTAL AMOUNT'), 'type': 'number'}
|
||||
headers['id'] = {'desc': self.tr('ID'), 'type': 'char'}
|
||||
headers['number'] = {'desc': self.tr('NUMBER'), 'type': 'char'}
|
||||
headers['invoice_number'] = {'desc': self.tr('INVOICE'), 'type': 'char'}
|
||||
headers['party.name'] = {'desc': self.tr('PARTY'), 'type': 'char'}
|
||||
headers['sale_date'] = {'desc': self.tr('DATE'), 'type': 'char'}
|
||||
headers['salesman.name'] = {'desc': self.tr('SALESMAN'), 'type': 'char'}
|
||||
headers['position'] = {'desc': self.tr('POSITION'), 'type': 'char'}
|
||||
headers['total_amount_cache'] = {'desc': self.tr('TOTAL AMOUNT'), 'type': 'number'}
|
||||
|
||||
widths = [20, 100, 150, 100, 90, 150, 100, 100]
|
||||
title = parent.tr('SEARCH SALES...')
|
||||
title = self.tr('SEARCH SALES...')
|
||||
methods = {
|
||||
'on_selected_method': 'on_selected_sale',
|
||||
'on_return_method': 'on_selected_sale'
|
||||
}
|
||||
super(SearchSale, self).__init__(parent, headers, None, methods, filter_column=[1, 2, 3, 4],
|
||||
cols_width=widths, title=title, fill=True)
|
||||
return SearchWindow(self._parent, headers, None, methods, filter_column=[1, 2, 3, 4],
|
||||
cols_width=widths, title=title, fill=True)
|
||||
|
||||
|
||||
class SearchParty(SearchWindow):
|
||||
class SearchParty(QWidget):
|
||||
def __init__(self, parent):
|
||||
headers = OrderedDict()
|
||||
headers['id'] = {'desc': parent.tr('ID'), 'type': 'char'}
|
||||
headers['id_number'] = {'desc': parent.tr('ID NUMBER'), 'type': 'char'}
|
||||
headers['name'] = {'desc': parent.tr('NAME'), 'type': 'char'}
|
||||
headers['street'] = {'desc': parent.tr('ADDRESS'), 'type': 'char'}
|
||||
headers['phone'] = {'desc': parent.tr('PHONE'), 'type': 'char'}
|
||||
super(SearchParty, self).__init__(parent)
|
||||
self._parent = parent
|
||||
|
||||
title = parent.tr('SEARCH CUSTOMER')
|
||||
def get(self):
|
||||
headers = OrderedDict()
|
||||
headers['id'] = {'desc': self.tr('ID'), 'type': 'char'}
|
||||
headers['id_number'] = {'desc': self.tr('ID NUMBER'), 'type': 'char'}
|
||||
headers['name'] = {'desc': self.tr('NAME'), 'type': 'char'}
|
||||
headers['street'] = {'desc': self.tr('ADDRESS'), 'type': 'char'}
|
||||
headers['phone'] = {'desc': self.tr('PHONE'), 'type': 'char'}
|
||||
|
||||
title = self.tr('SEARCH CUSTOMER')
|
||||
methods = {
|
||||
'on_selected_method': 'on_selected_party',
|
||||
'on_return_method': 'on_search_party',
|
||||
}
|
||||
super(SearchParty, self).__init__(parent, headers, None, methods,
|
||||
filter_column=[], cols_width=[60, 120, 270, 190, 90],
|
||||
title=title, fill=True)
|
||||
return SearchWindow(self._parent, headers, None, methods,
|
||||
filter_column=[], cols_width=[60, 120, 270, 190, 90],
|
||||
title=title, fill=True)
|
||||
|
||||
|
||||
class SearchProduct(SearchWindow):
|
||||
class SearchProduct(QWidget):
|
||||
def __init__(self, parent):
|
||||
super(SearchProduct, self).__init__(parent)
|
||||
self._parent = parent
|
||||
|
||||
def get(self):
|
||||
_cols_width = [10, 80]
|
||||
headers = OrderedDict()
|
||||
headers['id'] = {'desc': parent.tr('ID'), 'type': 'char'}
|
||||
headers['code'] = {'desc': parent.tr('CODE'), 'type': 'char'}
|
||||
if parent._config.get('show_stock_pos') in ['icon', 'value']:
|
||||
headers['quantity'] = {'desc': parent.tr('STOCK'), 'type': 'char'}
|
||||
if parent._config['show_stock_pos'] == 'icon':
|
||||
headers['id'] = {'desc': self.tr('ID'), 'type': 'char'}
|
||||
headers['code'] = {'desc': self.tr('CODE'), 'type': 'char'}
|
||||
if self._parent._config.get('show_stock_pos') in ['icon', 'value']:
|
||||
headers['quantity'] = {'desc': self.tr('STOCK'), 'type': 'char'}
|
||||
if self._parent._config['show_stock_pos'] == 'icon':
|
||||
headers['quantity']['icon'] = 'stock'
|
||||
headers['quantity']['type'] = 'icon'
|
||||
_cols_width.append(60)
|
||||
|
||||
headers['name'] = {'desc': parent.tr('NAME'), 'type': 'char'}
|
||||
headers['name'] = {'desc': self.tr('NAME'), 'type': 'char'}
|
||||
_cols_width.append(350)
|
||||
|
||||
if parent._config.get('show_description_pos'):
|
||||
headers['description'] = {'desc': parent.tr('DESCRIPTION'), 'type': 'char'}
|
||||
if self._parent._config.get('show_description_pos'):
|
||||
headers['description'] = {'desc': self.tr('DESCRIPTION'), 'type': 'char'}
|
||||
_cols_width.append(300)
|
||||
|
||||
if parent._config.get('show_brand'):
|
||||
headers['template.brand'] = {'desc': parent.tr('BRAND'), 'type': 'char'}
|
||||
if self._parent._config.get('show_brand'):
|
||||
headers['template.brand'] = {'desc': self.tr('BRAND'), 'type': 'char'}
|
||||
_cols_width.append(100)
|
||||
|
||||
price = {'desc': parent.tr('PRICE'), 'type': 'number'}
|
||||
if not parent._config.get('encoded_sale_price'):
|
||||
price = {'desc': self.tr('PRICE'), 'type': 'number'}
|
||||
if not self._parent._config.get('encoded_sale_price'):
|
||||
headers['template.sale_price_w_tax'] = price
|
||||
else:
|
||||
price['type'] = 'char'
|
||||
|
@ -89,244 +96,206 @@ class SearchProduct(SearchWindow):
|
|||
|
||||
_cols_width.append(100)
|
||||
|
||||
if parent._config.get('show_location_pos'):
|
||||
headers['location.name'] = {'desc': parent.tr('LOCATION'), 'type': 'char'}
|
||||
if self._parent._config.get('show_location_pos'):
|
||||
headers['location.name'] = {'desc': self.tr('LOCATION'), 'type': 'char'}
|
||||
_cols_width.append(100)
|
||||
|
||||
if parent._config['show_product_image']:
|
||||
headers['image'] = {'desc': parent.tr('IMAGE'), 'icon': 'image', 'type': 'icon'}
|
||||
if self._parent._config['show_product_image']:
|
||||
headers['image'] = {'desc': self.tr('IMAGE'), 'icon': 'image', 'type': 'icon'}
|
||||
_cols_width.append(30)
|
||||
|
||||
methods = {
|
||||
'on_selected_method': 'on_selected_product',
|
||||
'on_return_method': 'on_search_product',
|
||||
'image': parent.on_selected_icon_product,
|
||||
'quantity': parent.on_selected_stock_product
|
||||
'image': self._parent.on_selected_icon_product,
|
||||
'quantity': self._parent.on_selected_stock_product
|
||||
}
|
||||
|
||||
super(SearchProduct, self).__init__(parent, headers, None, methods,
|
||||
cols_width=_cols_width, fill=True)
|
||||
return SearchWindow(self._parent, headers, None, methods,
|
||||
cols_width=_cols_width, fill=True)
|
||||
|
||||
|
||||
class DialogManageTables(QuickDialog):
|
||||
def __init__(self, parent, kind):
|
||||
if not parent._Tables:
|
||||
class DialogManageTables(QWidget):
|
||||
def __init__(self, parent):
|
||||
super(DialogManageTables, self).__init__(parent)
|
||||
self._parent = parent
|
||||
|
||||
def get(self, kind):
|
||||
if not self._Tables:
|
||||
return
|
||||
tables = parent._Tables.find([
|
||||
('shop', '=', parent.shop['id'])
|
||||
tables = self._Tables.find([
|
||||
('shop', '=', self.shop['id'])
|
||||
])
|
||||
_tables = ManageTables(parent, tables, self.action_table_assigned)
|
||||
super(DialogManageTables, self).__init__(parent, kind, widgets=[_tables])
|
||||
_tables = ManageTables(self._parent, tables, self.action_table_assigned)
|
||||
return QuickDialog(self._parent, kind, widgets=[_tables])
|
||||
|
||||
def action_table_assigned(self, id, name, prev_state, new_state):
|
||||
table_assigned = id
|
||||
class DialogConsumer(QWidget):
|
||||
def __init__(self, parent):
|
||||
super(DialogConsumer, self).__init__(parent)
|
||||
self._parent = parent
|
||||
|
||||
if self.parent._sale.get('table_assigned') != id and prev_state == 'occupied':
|
||||
return False
|
||||
|
||||
if self.parent._sale.get('table_assigned') == id and new_state == 'available':
|
||||
name = ''
|
||||
table_assigned = None
|
||||
|
||||
self.parent._sale['table_assigned'] = table_assigned
|
||||
self.parent._sale['table_assigned.state'] = new_state
|
||||
|
||||
self.parent._Tables.write([id], {'state': new_state})
|
||||
|
||||
self.parent._PosSale.write([self.parent._sale['id']], {'table_assigned': table_assigned})
|
||||
self.parent.field_table_assigned.setText(name)
|
||||
return True
|
||||
|
||||
|
||||
class DialogConsumer(QuickDialog):
|
||||
def __init__(self, parent, kind):
|
||||
parent.state_consumer = {}
|
||||
parent._consumer = None
|
||||
def get(self, kind):
|
||||
self._parent.state_consumer = {}
|
||||
self._parent._consumer = None
|
||||
vbox_consumer = QVBoxLayout()
|
||||
grid = QGridLayout()
|
||||
|
||||
label_phone = QLabel(parent.tr('PHONE:'))
|
||||
label_phone = QLabel(self.tr('PHONE:'))
|
||||
label_phone.setObjectName('label_phone')
|
||||
grid.addWidget(label_phone, 1, 1)
|
||||
parent.row_field_phone = QLineEdit()
|
||||
parent.row_field_phone.setObjectName('row_field_phone')
|
||||
parent.row_field_phone.editingFinished.connect(
|
||||
lambda: self.update_consumer_data('phone')
|
||||
self._parent.row_field_phone = QLineEdit()
|
||||
self._parent.row_field_phone.setObjectName('row_field_phone')
|
||||
self._parent.row_field_phone.editingFinished.connect(
|
||||
lambda: self._parent.update_consumer_data('phone')
|
||||
)
|
||||
grid.addWidget(parent.row_field_phone, 1, 2)
|
||||
grid.addWidget(self._parent.row_field_phone, 1, 2)
|
||||
|
||||
label_consumer = QLabel(parent.tr('CONSUMER:'))
|
||||
label_consumer = QLabel(self.tr('CONSUMER:'))
|
||||
label_consumer.setObjectName('label_consumer')
|
||||
grid.addWidget(label_consumer, 2, 1)
|
||||
parent.row_field_consumer = QLineEdit()
|
||||
parent.row_field_consumer.setObjectName('row_field_consumer')
|
||||
parent.row_field_consumer.textChanged.connect(
|
||||
lambda: self.update_consumer_data('name')
|
||||
self._parent.row_field_consumer = QLineEdit()
|
||||
self._parent.row_field_consumer.setObjectName('row_field_consumer')
|
||||
self._parent.row_field_consumer.textChanged.connect(
|
||||
lambda: self._parent.update_consumer_data('name')
|
||||
)
|
||||
grid.addWidget(parent.row_field_consumer, 2, 2)
|
||||
grid.addWidget(self.row_field_consumer, 2, 2)
|
||||
|
||||
label_address = QLabel(parent.tr('ADDRESS:'))
|
||||
label_address = QLabel(self.tr('ADDRESS:'))
|
||||
label_address.setObjectName('label_address')
|
||||
grid.addWidget(label_address, 3, 1)
|
||||
parent.row_field_address = QLineEdit()
|
||||
parent.row_field_address.setObjectName('row_field_address')
|
||||
parent.row_field_address.textChanged.connect(
|
||||
lambda: self.update_consumer_data('address')
|
||||
self._parent.row_field_address = QLineEdit()
|
||||
self._parent.row_field_address.setObjectName('row_field_address')
|
||||
self._parent.row_field_address.textChanged.connect(
|
||||
lambda: self._parent.update_consumer_data('address')
|
||||
)
|
||||
grid.addWidget(parent.row_field_address, 3, 2)
|
||||
grid.addWidget(self.row_field_address, 3, 2)
|
||||
|
||||
label_id_number = QLabel(parent.tr('ID NUMBER:'))
|
||||
label_id_number = QLabel(self.tr('ID NUMBER:'))
|
||||
label_id_number.setObjectName('label_id_number')
|
||||
grid.addWidget(label_id_number, 4, 1)
|
||||
parent.row_field_id_number = QLineEdit()
|
||||
parent.row_field_id_number.setObjectName('row_field_id_number')
|
||||
parent.row_field_id_number.textChanged.connect(
|
||||
lambda: self.update_consumer_data('id_number')
|
||||
self._parent.row_field_id_number = QLineEdit()
|
||||
self._parent.row_field_id_number.setObjectName('row_field_id_number')
|
||||
self._parent.row_field_id_number.textChanged.connect(
|
||||
lambda: self._parent.update_consumer_data('id_number')
|
||||
)
|
||||
grid.addWidget(parent.row_field_id_number, 4, 2)
|
||||
grid.addWidget(self._parent.row_field_id_number, 4, 2)
|
||||
|
||||
label_birthday = QLabel(parent.tr('BIRTHDAY:'))
|
||||
label_birthday = QLabel(self.tr('BIRTHDAY:'))
|
||||
label_birthday.setObjectName('label_birthday')
|
||||
grid.addWidget(label_birthday, 5, 1)
|
||||
item_date = QDateEdit()
|
||||
item_date.setGeometry(QRect(120, 18, 140, 18))
|
||||
item_date.setDisplayFormat('dd/MM/yyyy')
|
||||
item_date.setCalendarPopup(True)
|
||||
parent.row_field_birthday = item_date
|
||||
parent.row_field_birthday.setObjectName('row_field_birthday')
|
||||
parent.row_field_birthday.dateTimeChanged.connect(
|
||||
lambda: self.update_consumer_data('birthday')
|
||||
self._parent.row_field_birthday = item_date
|
||||
self._parent.row_field_birthday.setObjectName('row_field_birthday')
|
||||
self._parent.row_field_birthday.dateTimeChanged.connect(
|
||||
lambda: self._parent.update_consumer_data('birthday')
|
||||
)
|
||||
grid.addWidget(parent.row_field_birthday, 5, 2)
|
||||
grid.addWidget(self._parent.row_field_birthday, 5, 2)
|
||||
|
||||
vbox_consumer.addLayout(grid)
|
||||
super(DialogConsumer, self).__init__(parent, kind, widgets=[vbox_consumer])
|
||||
self.setWindowTitle('CONSUMER')
|
||||
self.accepted.connect(self.dialog_search_consumer_accepted)
|
||||
dialog = QuickDialog(self._parent, kind, widgets=[vbox_consumer])
|
||||
dialog.setWindowTitle('CONSUMER')
|
||||
dialog.accepted.connect(self._parent.dialog_search_consumer_accepted)
|
||||
|
||||
def clear_dialog(self):
|
||||
self.parent.row_field_phone.setText('')
|
||||
self.parent.row_field_address.setText('')
|
||||
self.parent.row_field_consumer.setText('')
|
||||
self.parent.row_field_id_number.setText('')
|
||||
# self.row_field_birthday.setDate(QDate.currentDate())
|
||||
|
||||
def dialog_search_consumer_accepted(self):
|
||||
if not self.parent.state_consumer:
|
||||
return
|
||||
if self.parent._consumer:
|
||||
res = self.parent.ModSale.update_consumer({
|
||||
'id': self.parent._consumer['id'],
|
||||
'fields': self.parent.state_consumer,
|
||||
})
|
||||
if res['msg'] != 'ok':
|
||||
print('error')
|
||||
else:
|
||||
res = self.parent.ModSale.create_consumer({
|
||||
'fields': self.parent.state_consumer,
|
||||
})
|
||||
if res['msg'] != 'ok':
|
||||
print('error')
|
||||
|
||||
def update_consumer_data(self, field=''):
|
||||
if field == 'address':
|
||||
self.parent.state_consumer['address'] = self.parent.row_field_address.text()
|
||||
elif field == 'id_number':
|
||||
self.parent.state_consumer['id_number'] = self.parent.row_field_id_number.text()
|
||||
elif field == 'name':
|
||||
self.parent.state_consumer['name'] = self.parent.row_field_consumer.text()
|
||||
elif field == 'birthday':
|
||||
self.parent.state_consumer['birthday'] = self.parent.row_field_birthday.date().toPyDate()
|
||||
elif field == 'phone':
|
||||
self.parent._text_field_phone = self.parent.row_field_phone.text()
|
||||
if self.parent._text_field_phone:
|
||||
self.parent.state_consumer['phone'] = self.parent._text_field_phone
|
||||
consumers = self.parent.PartyConsumer.find([
|
||||
('phone', '=', self.parent._text_field_phone),
|
||||
])
|
||||
if not consumers:
|
||||
self.parent._consumer = {}
|
||||
self.parent.row_field_address.setText('')
|
||||
self.parent.row_field_consumer.setText('')
|
||||
self.parent.row_field_id_number.setText('')
|
||||
self.parent.row_field_birthday.setDate()
|
||||
else:
|
||||
self.parent._consumer = consumers[0]
|
||||
self.parent.row_field_address.setText(self.parent._consumer['address'])
|
||||
self.parent.row_field_consumer.setText(self.parent._consumer['name'])
|
||||
self.parent.row_field_id_number.setText(self.parent._consumer['id_number'])
|
||||
if self.parent._consumer.get('birthday'):
|
||||
y, m, d = self.parent._consumer['birthday'].split('-')
|
||||
self.parent.row_field_birthday.setDate(QDate(int(y), int(m), int(d)))
|
||||
return dialog
|
||||
|
||||
|
||||
class DialogAgent(QuickDialog):
|
||||
def __init__(self, parent, kind):
|
||||
class DialogAgent(QWidget):
|
||||
def __init__(self, parent):
|
||||
super(DialogAgent, self).__init__(parent)
|
||||
self._parent = parent
|
||||
|
||||
def get(self, kind):
|
||||
view = [
|
||||
('agent_ask', {
|
||||
'name': parent.tr('AGENT'),
|
||||
'name': self.tr('AGENT'),
|
||||
'type': 'relation',
|
||||
'model': parent.Agent,
|
||||
'model': self.Agent,
|
||||
'domain': [],
|
||||
'fields': [
|
||||
('id', parent.tr('ID')),
|
||||
('party.rec_name', parent.tr('NAME')),
|
||||
('party.id_number', parent.tr('ID NUMBER')),
|
||||
('id', self.tr('ID')),
|
||||
('party.rec_name', self.tr('NAME')),
|
||||
('party.id_number', self.tr('ID NUMBER')),
|
||||
]}),
|
||||
('commission_ask', {'name': parent.tr('COMMISSION')}),
|
||||
('commission_amount', {'name': parent.tr('AMOUNT'), 'readonly': True}),
|
||||
('commission_ask', {'name': self.tr('COMMISSION')}),
|
||||
('commission_amount', {'name': self.tr('AMOUNT'), 'readonly': True}),
|
||||
]
|
||||
super(DialogAgent, self).__init__(parent, kind, data=view)
|
||||
return QuickDialog(self._parent, kind, data=view)
|
||||
|
||||
|
||||
class DialogCancelInvoice(QuickDialog):
|
||||
def __init__(self, parent, kind):
|
||||
class DialogCancelInvoice(QWidget):
|
||||
def __init__(self, parent):
|
||||
super(DialogCancelInvoice, self).__init__(parent)
|
||||
self._parent = parent
|
||||
|
||||
def get(self, kind):
|
||||
view = [
|
||||
('password_for_cancel_ask', {
|
||||
'name': parent.tr('INSERT PASSWORD FOR CANCEL'),
|
||||
'name': self.tr('INSERT PASSWORD FOR CANCEL'),
|
||||
'password': True
|
||||
}),
|
||||
]
|
||||
super(DialogCancelInvoice, self).__init__(parent, kind, data=view)
|
||||
return QuickDialog(self._parent, kind, data=view)
|
||||
|
||||
|
||||
class DialogForceAssing(QuickDialog):
|
||||
def __init__(self, parent, kind):
|
||||
class DialogForceAssign(QWidget):
|
||||
def __init__(self, parent):
|
||||
super(DialogForceAssign, self).__init__(parent)
|
||||
self._parent = parent
|
||||
|
||||
def get(self, kind):
|
||||
field = 'password_force_assign_ask'
|
||||
data = {'name': parent.tr('PASSWORD FORCE ASSIGN')}
|
||||
super(DialogForceAssing, self).__init__(parent, kind, data=[(field, data)])
|
||||
data = {'name': self.tr('PASSWORD FORCE ASSIGN')}
|
||||
return QuickDialog(self._parent, kind, data=[(field, data)])
|
||||
|
||||
|
||||
class DialogOrder(QuickDialog):
|
||||
def __init__(self, parent, kind):
|
||||
string = parent.tr('DO YOU WANT TO CONFIRM THE SEND ORDER?')
|
||||
super(DialogOrder, self).__init__(parent, kind, string, data=[])
|
||||
class DialogOrder(QWidget):
|
||||
def __init__(self, parent):
|
||||
super(DialogOrder, self).__init__(parent)
|
||||
self._parent = parent
|
||||
|
||||
def get(self, kind):
|
||||
string = self.tr('DO YOU WANT TO CONFIRM THE SEND ORDER?')
|
||||
return QuickDialog(self._parent, kind, string, data=[])
|
||||
|
||||
|
||||
class Dialogstock(QuickDialog):
|
||||
def __init__(self, parent, kind):
|
||||
class DialogStock(QWidget):
|
||||
def __init__(self, parent):
|
||||
super(DialogStock, self).__init__(parent)
|
||||
self._parent = parent
|
||||
|
||||
def get(self, kind):
|
||||
data = {
|
||||
'name': 'stock',
|
||||
'values': [],
|
||||
'heads': [parent.tr('WAREHOUSE'), parent.tr('QUANTITY')],
|
||||
'heads': [self.tr('WAREHOUSE'), self.tr('QUANTITY')],
|
||||
}
|
||||
label = parent.tr('STOCK BY PRODUCT:')
|
||||
super(Dialogstock, self).__init__(parent, kind, label, data, readonly=True)
|
||||
label = self.tr('STOCK BY PRODUCT:')
|
||||
return QuickDialog(self._parent, kind, label, data, readonly=True)
|
||||
|
||||
|
||||
class DialogGlobalDiscount(QuickDialog):
|
||||
def __init__(self, parent, kind):
|
||||
class DialogGlobalDiscount(QWidget):
|
||||
def __init__(self, parent):
|
||||
super(DialogGlobalDiscount, self).__init__(parent)
|
||||
self._parent = parent
|
||||
|
||||
def get(self, kind):
|
||||
field = 'global_discount_ask'
|
||||
data = {'name': parent.tr('GLOBAL DISCOUNT')}
|
||||
super(DialogGlobalDiscount, self).__init__(parent, kind, data=[(field, data)])
|
||||
data = {'name': self.tr('GLOBAL DISCOUNT')}
|
||||
return QuickDialog(self._parent, kind, data=[(field, data)])
|
||||
|
||||
|
||||
class DialogPrintInvoice(QuickDialog):
|
||||
def __init__(self, parent, kind):
|
||||
class DialogPrintInvoice(QWidget):
|
||||
def __init__(self, parent):
|
||||
super(DialogPrintInvoice, self).__init__(parent)
|
||||
self._parent = parent
|
||||
|
||||
def get(self, kind):
|
||||
view = [
|
||||
('invoice_number_ask', {'name': parent.tr('INVOICE NUMBER')}),
|
||||
('invoice_number_ask', {'name': self.tr('INVOICE NUMBER')}),
|
||||
('printer_ask', {
|
||||
'name': parent.tr('PRINTER'),
|
||||
'name': self.tr('PRINTER'),
|
||||
'type': 'selection',
|
||||
'values': [
|
||||
(1, 'POS'),
|
||||
|
@ -334,236 +303,193 @@ class DialogPrintInvoice(QuickDialog):
|
|||
],
|
||||
}),
|
||||
('type_ask', {
|
||||
'name': parent.tr('TYPE'),
|
||||
'name': self.tr('TYPE'),
|
||||
'type': 'selection',
|
||||
'values': [
|
||||
('invoice', parent.tr('INVOICE')),
|
||||
('order', parent.tr('ORDER'))
|
||||
('invoice', self.tr('INVOICE')),
|
||||
('order', self.tr('ORDER'))
|
||||
],
|
||||
}),
|
||||
]
|
||||
super(DialogPrintInvoice, self).__init__(parent, kind, data=view)
|
||||
return QuickDialog(self._parent, kind, data=view)
|
||||
|
||||
|
||||
class DialogVoucher(QWidget):
|
||||
def __init__(self, parent):
|
||||
super(DialogVoucher, self).__init__(parent)
|
||||
self._parent = parent
|
||||
|
||||
class DialogVoucher(QuickDialog):
|
||||
def __init__(self, parent, kind):
|
||||
def get(self, kind):
|
||||
field = 'voucher_ask'
|
||||
data = {'name': parent.tr('VOUCHER NUMBER')}
|
||||
super(DialogVoucher, self).__init__(parent, kind, data=[(field, data)])
|
||||
data = {'name': self.tr('VOUCHER NUMBER')}
|
||||
return QuickDialog(self._parent, kind, data=[(field, data)])
|
||||
|
||||
|
||||
class DialogSalesman(QWidget):
|
||||
def __init__(self, parent):
|
||||
super(DialogSalesman, self).__init__(parent)
|
||||
self._parent = parent
|
||||
|
||||
class DialogSalesman(QuickDialog):
|
||||
def __init__(self, parent, kind):
|
||||
def get(self, kind):
|
||||
data = {
|
||||
'name': 'salesman',
|
||||
'values': [(str(e['id']), e['party']['name'])
|
||||
for e in parent.employees],
|
||||
'heads': [parent.tr('Id'), parent.tr('Salesman')],
|
||||
for e in self._parent.employees],
|
||||
'heads': [self.tr('Id'), self.tr('Salesman')],
|
||||
}
|
||||
string = parent.tr('CHOOSE SALESMAN')
|
||||
super(DialogSalesman, self).__init__(parent, kind, string, data)
|
||||
string = self.tr('CHOOSE SALESMAN')
|
||||
return QuickDialog(self._parent, kind, string, data)
|
||||
|
||||
|
||||
class DialogTaxes(QuickDialog):
|
||||
def __init__(self, parent, kind):
|
||||
if parent.shop_taxes:
|
||||
taxes = [(str(e['id']), e['name']) for e in parent.shop_taxes]
|
||||
class DialogTaxes(QWidget):
|
||||
def __init__(self, parent):
|
||||
super(DialogTaxes, self).__init__(parent)
|
||||
self._parent = parent
|
||||
|
||||
def get(self, kind):
|
||||
if self._parent.shop_taxes:
|
||||
taxes = [(str(e['id']), e['name']) for e in self._parent.shop_taxes]
|
||||
else:
|
||||
taxes = []
|
||||
data = {
|
||||
'name': 'tax',
|
||||
'values': taxes,
|
||||
'heads': [parent.tr('Id'), parent.tr('Salesman')],
|
||||
'heads': [self.tr('Id'), self.tr('Salesman')],
|
||||
}
|
||||
string = parent.tr('CHOOSE TAX')
|
||||
super(DialogTaxes, self).__init__(parent, kind, string, data)
|
||||
string = self.tr('CHOOSE TAX')
|
||||
return QuickDialog(self._parent, kind, string, data)
|
||||
|
||||
|
||||
class DialogPaymentTerm(QuickDialog):
|
||||
def __init__(self, parent, kind):
|
||||
class DialogPaymentTerm(QWidget):
|
||||
def __init__(self, parent):
|
||||
super(DialogPaymentTerm, self).__init__(parent)
|
||||
self._parent = parent
|
||||
|
||||
def get(self, kind):
|
||||
data = {
|
||||
'name': 'payment_term',
|
||||
'values': [(p_id, parent._payment_terms[p_id]['name'])
|
||||
for p_id in parent._payment_terms],
|
||||
'heads': [parent.tr('ID'), parent.tr('PAYMENT TERM')],
|
||||
'values': [(p_id, self._parent._payment_terms[p_id]['name'])
|
||||
for p_id in self._parent._payment_terms],
|
||||
'heads': [self.tr('ID'), self.tr('PAYMENT TERM')],
|
||||
}
|
||||
string = parent.tr('SELECT PAYMENT TERM')
|
||||
super(DialogPaymentTerm, self).__init__(parent, kind, string, data)
|
||||
string = self.tr('SELECT PAYMENT TERM')
|
||||
return QuickDialog(self._parent, kind, string, data)
|
||||
|
||||
|
||||
class DialogPayment(QuickDialog):
|
||||
def __init__(self, parent, kind):
|
||||
class DialogPayment(QWidget):
|
||||
def __init__(self, parent):
|
||||
super(DialogPayment, self).__init__(parent)
|
||||
self._parent = parent
|
||||
|
||||
def get(self, kind):
|
||||
data = {
|
||||
'name': 'journal',
|
||||
'values': sorted([(str(j), parent._journals[j]['name'])
|
||||
for j in parent._journals]),
|
||||
'heads': [parent.tr('ID'), parent.tr('PAYMENT MODE:')],
|
||||
'values': sorted([(str(j), self._parent._journals[j]['name'])
|
||||
for j in self._parent._journals]),
|
||||
'heads': [self.tr('ID'), self.tr('PAYMENT MODE:')],
|
||||
}
|
||||
string = parent.tr('SELECT PAYMENT MODE:')
|
||||
super(DialogPayment, self).__init__(parent, kind, string, data)
|
||||
string = self.tr('SELECT PAYMENT MODE:')
|
||||
return QuickDialog(self._parent, kind, string, data)
|
||||
|
||||
|
||||
class Position(QuickDialog):
|
||||
def __init__(self, parent, kind):
|
||||
class Position(QWidget):
|
||||
def __init__(self, parent):
|
||||
super(Position, self).__init__(parent)
|
||||
self._parent = parent
|
||||
|
||||
def get(self, kind):
|
||||
_field = 'position_ask'
|
||||
_data = {'name': parent.tr('POSITION')}
|
||||
super(Position, self).__init__(parent, kind, data=[(_field, _data)])
|
||||
_data = {'name': self.tr('POSITION')}
|
||||
return QuickDialog(self._parent, kind, data=[(_field, _data)])
|
||||
|
||||
|
||||
class Comment(QuickDialog):
|
||||
def __init__(self, parent, kind):
|
||||
class Comment(QWidget):
|
||||
def __init__(self, parent):
|
||||
super(Comment, self).__init__(parent)
|
||||
self._parent = parent
|
||||
|
||||
def get(self, kind):
|
||||
_field = 'comment_ask'
|
||||
_data = {'name': parent.tr('COMMENTS'), 'widget': 'text'}
|
||||
super(Comment, self).__init__(parent, kind, data=[(_field, _data)])
|
||||
_data = {'name': self.tr('COMMENTS'), 'widget': 'text'}
|
||||
return QuickDialog(self._parent, kind, data=[(_field, _data)])
|
||||
|
||||
|
||||
class SaleLine(QuickDialog):
|
||||
def __init__(self, parent, kind):
|
||||
parent.state_line = {}
|
||||
class SaleLine(QWidget):
|
||||
def __init__(self, parent):
|
||||
super(SaleLine, self).__init__(parent)
|
||||
self._parent = parent
|
||||
|
||||
def get(self, kind):
|
||||
self._parent.state_line = {}
|
||||
vbox_product = QVBoxLayout()
|
||||
grid = QGridLayout()
|
||||
qty = 2
|
||||
|
||||
parent.label_product = QLabel()
|
||||
parent.label_product.setAlignment(alignCenter)
|
||||
parent.label_product.setObjectName('label_product')
|
||||
vbox_product.addWidget(parent.label_product)
|
||||
parent.row_field_description = QLineEdit()
|
||||
parent.row_field_description.setObjectName('row_field_description')
|
||||
parent.row_field_description.textChanged.connect(
|
||||
lambda: self.update_sale_line('description')
|
||||
self._parent.label_product = QLabel()
|
||||
self._parent.label_product.setAlignment(alignCenter)
|
||||
self._parent.label_product.setObjectName('label_product')
|
||||
vbox_product.addWidget(self._parent.label_product)
|
||||
self._parent.row_field_description = QLineEdit()
|
||||
self._parent.row_field_description.setObjectName('row_field_description')
|
||||
self._parent.row_field_description.textChanged.connect(
|
||||
lambda: self._parent.update_sale_line('description')
|
||||
)
|
||||
grid.addWidget(parent.row_field_description, 1, 1, 1, 2)
|
||||
grid.addWidget(self._parent.row_field_description, 1, 1, 1, 2)
|
||||
|
||||
if parent._config.get('show_fractions'):
|
||||
label_fraction = QLabel(parent.tr('FRACTION:'))
|
||||
if self._parent._config.get('show_fractions'):
|
||||
label_fraction = QLabel(self.tr('FRACTION:'))
|
||||
label_fraction.setObjectName('label_fraction')
|
||||
grid.addWidget(label_fraction, 2, 1)
|
||||
parent.field_combobox_fraction = ComboBox(parent, 'fraction',
|
||||
self._parent.field_combobox_fraction = ComboBox(self._parent, 'fraction',
|
||||
{'values': FRACTIONS})
|
||||
grid.addWidget(parent.field_combobox_fraction, 2, 2)
|
||||
parent.field_combobox_fraction.currentIndexChanged.connect(
|
||||
lambda: self.update_sale_line('qty_fraction')
|
||||
grid.addWidget(self._parent.field_combobox_fraction, 2, 2)
|
||||
self._parent.field_combobox_fraction.currentIndexChanged.connect(
|
||||
lambda: self._parent.update_sale_line('qty_fraction')
|
||||
)
|
||||
|
||||
label_qty = QLabel(parent.tr('QUANTITY:'))
|
||||
label_qty = QLabel(self.tr('QUANTITY:'))
|
||||
label_qty.setObjectName('label_qty')
|
||||
grid.addWidget(label_qty, 3, 1)
|
||||
parent.row_field_qty = QDoubleSpinBox()
|
||||
parent.row_field_qty.setObjectName('row_field_qty')
|
||||
parent.row_field_qty.setMinimum(0)
|
||||
parent.row_field_qty.setMaximum(100000)
|
||||
if parent._config.get('decimals_digits_quantity'):
|
||||
qty = parent._config['decimals_digits_quantity']
|
||||
self._parent.row_field_qty = QDoubleSpinBox()
|
||||
self._parent.row_field_qty.setObjectName('row_field_qty')
|
||||
self._parent.row_field_qty.setMinimum(0)
|
||||
self._parent.row_field_qty.setMaximum(100000)
|
||||
if self._parent._config.get('decimals_digits_quantity'):
|
||||
qty = self._parent._config['decimals_digits_quantity']
|
||||
|
||||
parent.row_field_qty.setDecimals(qty)
|
||||
parent.row_field_qty.setAlignment(alignCenter)
|
||||
grid.addWidget(parent.row_field_qty, 3, 2)
|
||||
parent.row_field_qty.valueChanged.connect(
|
||||
lambda: self.update_sale_line('quantity')
|
||||
self._parent.row_field_qty.setDecimals(qty)
|
||||
self._parent.row_field_qty.setAlignment(alignCenter)
|
||||
grid.addWidget(self._parent.row_field_qty, 3, 2)
|
||||
self._parent.row_field_qty.valueChanged.connect(
|
||||
lambda: self._parent.update_sale_line('quantity')
|
||||
)
|
||||
|
||||
label_price = QLabel(parent.tr('UNIT PRICE:'))
|
||||
label_price = QLabel(self.tr('UNIT PRICE:'))
|
||||
label_price.setObjectName('label_price')
|
||||
grid.addWidget(label_price, 4, 1)
|
||||
parent.row_field_price = FieldMoney(parent, 'row_field_price', {}, readonly=False)
|
||||
parent.row_field_price.setObjectName('row_field_price')
|
||||
grid.addWidget(parent.row_field_price, 4, 2)
|
||||
parent.row_field_price.textChanged.connect(
|
||||
lambda: self.update_sale_line('unit_price')
|
||||
self._parent.row_field_price = FieldMoney(self, 'row_field_price', {}, readonly=False)
|
||||
self._parent.row_field_price.setObjectName('row_field_price')
|
||||
grid.addWidget(self._parent.row_field_price, 4, 2)
|
||||
self._parent.row_field_price.textChanged.connect(
|
||||
lambda: self._parent.update_sale_line('unit_price')
|
||||
)
|
||||
|
||||
parent.row_field_note = QTextEdit('')
|
||||
parent.row_field_note.setObjectName('row_field_note')
|
||||
grid.addWidget(parent.row_field_note, 5, 1, 5, 2)
|
||||
parent.row_field_note.textChanged.connect(
|
||||
lambda: self.update_sale_line('note')
|
||||
self._parent.row_field_note = QTextEdit('')
|
||||
self._parent.row_field_note.setObjectName('row_field_note')
|
||||
grid.addWidget(self._parent.row_field_note, 5, 1, 5, 2)
|
||||
self._parent.row_field_note.textChanged.connect(
|
||||
lambda: self._parent.update_sale_line('note')
|
||||
)
|
||||
|
||||
vbox_product.addLayout(grid)
|
||||
super(SaleLine, self).__init__(parent, kind, widgets=[vbox_product])
|
||||
self.accepted.connect(self.dialog_product_edit_accepted)
|
||||
|
||||
def update_sale_line(self, field):
|
||||
value = None
|
||||
self.parent.state_line['id'] = self.parent._current_line_id
|
||||
if field == 'quantity':
|
||||
value = Decimal(self.parent.row_field_qty.value())
|
||||
if field == 'unit_price':
|
||||
value = self.parent.row_field_price.text()
|
||||
if field == 'qty_fraction':
|
||||
qty = self.parent.field_combobox_fraction.get_id()
|
||||
self.parent.row_field_qty.setValue(float(qty))
|
||||
value = self.parent.field_combobox_fraction.get_label()
|
||||
self.parent.state_line['quantity'] = qty
|
||||
price_ = self.parent.ModSale.get_product_prices({
|
||||
'ids': [self.parent._sale_line['product']['id']],
|
||||
'quantity': float(qty),
|
||||
'sale_id': self.parent._sale['id'],
|
||||
})
|
||||
if price_ and price_.get('unit_price_w_tax'):
|
||||
price_list = str(price_['unit_price_w_tax'])
|
||||
self.parent.row_field_price.setText(price_list)
|
||||
self.parent.state_line['unit_price'] = price_list
|
||||
|
||||
if field == 'description':
|
||||
value = self.parent.row_field_description.text()
|
||||
if field == 'note':
|
||||
value = self.parent.row_field_note.toPlainText()
|
||||
|
||||
if value:
|
||||
self.parent.state_line[field] = value
|
||||
|
||||
def dialog_product_edit_accepted(self):
|
||||
if not self.parent.state_line:
|
||||
return
|
||||
|
||||
_record = None
|
||||
|
||||
if self.parent.state_line.get('quantity'):
|
||||
quantity = self.parent.state_line.pop('quantity')
|
||||
_record = self.parent.ModSaleLine.faster_set_quantity({
|
||||
'id': self.parent._current_line_id,
|
||||
'quantity': to_float(quantity, 2)
|
||||
})
|
||||
|
||||
if self.parent.state_line.get('unit_price'):
|
||||
unit_price = self.parent.state_line.pop('unit_price')
|
||||
self.parent._sign = '/'
|
||||
self.parent._process_price(unit_price)
|
||||
self.parent._sign = None
|
||||
_record = self.parent.ModSaleLine.write([self.parent._current_line_id], {})
|
||||
|
||||
if self.parent.state_line.get('description'):
|
||||
_record = self.parent.ModSaleLine.write([self.parent._current_line_id], {
|
||||
'description': self.parent.state_line['description']
|
||||
})
|
||||
|
||||
if self.parent.state_line.get('note'):
|
||||
_record = self.parent.ModSaleLine.write([self.parent._current_line_id], {
|
||||
'note': self.parent.state_line['note']
|
||||
})
|
||||
|
||||
if _record:
|
||||
if not _record.get('unit.symbol'):
|
||||
_record['unit.symbol'] = _record['unit']['symbol']
|
||||
if not _record.get('product.template.name'):
|
||||
_record['product.template.name'] = _record['product']['template']['name']
|
||||
if not _record.get('product.code'):
|
||||
_record['product.code'] = _record['product']['code']
|
||||
self.parent.model_sale_lines.update_record(_record)
|
||||
|
||||
self.parent.update_total_amount()
|
||||
self.parent.state_line = {}
|
||||
dialog = QuickDialog(self._parent, kind, widgets=[vbox_product])
|
||||
dialog.accepted.connect(self._parent.dialog_product_edit_accepted)
|
||||
return dialog
|
||||
|
||||
|
||||
class Help(HelpDialog):
|
||||
|
||||
def __init__(self, parent):
|
||||
super(Help, self).__init__(parent)
|
||||
super(Help, self).__init__(self)
|
||||
shortcuts = [
|
||||
(self.tr('HELP'), 'F1'),
|
||||
(self.tr('SEARCH PRODUCT'), 'F2'),
|
||||
|
|
BIN
app/image_test.jpeg
Normal file
BIN
app/image_test.jpeg
Normal file
Binary file not shown.
After Width: | Height: | Size: 13 KiB |
BIN
app/locale/__init__.pyc
Normal file
BIN
app/locale/__init__.pyc
Normal file
Binary file not shown.
Binary file not shown.
File diff suppressed because it is too large
Load diff
|
@ -4,20 +4,20 @@ import sys
|
|||
import os
|
||||
import logging
|
||||
from decimal import Decimal
|
||||
from .dialogs import (Position, Comment, SearchParty, DialogPayment,
|
||||
DialogSalesman, DialogVoucher, DialogPrintInvoice,
|
||||
DialogGlobalDiscount, DialogPaymentTerm, SearchSale,
|
||||
Dialogstock, DialogOrder, DialogForceAssing, DialogTaxes,
|
||||
DialogCancelInvoice, SaleLine, DialogAgent, Help,
|
||||
DialogConsumer, DialogManageTables, SearchProduct)
|
||||
from PyQt5.QtCore import Qt, QThread, pyqtSignal, QDate
|
||||
from .tools import get_icon, to_float, to_numeric
|
||||
from .dialogs import (Help, SearchSale, SearchParty, SearchProduct, Position,
|
||||
Comment, DialogPayment, DialogSalesman, DialogVoucher, DialogPrintInvoice,
|
||||
DialogGlobalDiscount, DialogPaymentTerm, DialogStock, DialogOrder,
|
||||
DialogForceAssign, DialogTaxes, DialogCancelInvoice, SaleLine, DialogAgent,
|
||||
DialogConsumer, DialogManageTables)
|
||||
from datetime import datetime, timedelta, date
|
||||
from collections import OrderedDict
|
||||
from PyQt5.QtCore import Qt, QThread, pyqtSignal
|
||||
# from PyQt5.QtGui import QTouchEvent
|
||||
from PyQt5.QtWidgets import (QLabel, QHBoxLayout, QVBoxLayout,
|
||||
QWidget, QGridLayout, QLineEdit)
|
||||
from app.commons.action import Action
|
||||
from app.commons.forms import GridForm, FieldMoney, ComboBox
|
||||
from app.commons.forms import GridForm, ComboBox, FieldNumeric
|
||||
from app.commons.messages import MessageBar
|
||||
from app.commons.image import Image
|
||||
from app.commons.table import TableView
|
||||
|
@ -29,7 +29,6 @@ from .localdb import LocalStore
|
|||
from .reporting import Receipt
|
||||
from .buttonpad import Buttonpad
|
||||
from .states import STATES, RE_SIGN
|
||||
from .tools import get_icon, to_numeric
|
||||
from .constants import (PATH_PRINTERS, DELTA_LOCALE, STRETCH, alignRight,
|
||||
alignLeft, alignCenter, alignHCenter, alignVCenter,
|
||||
DIALOG_REPLY_NO, DIALOG_REPLY_YES, ZERO,
|
||||
|
@ -49,6 +48,7 @@ class MainWindow(FrontWindow):
|
|||
super(MainWindow, self).__init__(connection, params, title)
|
||||
print('Screen Size: > ', self.screen_size)
|
||||
_theme = params['theme'] if params.get('theme') else None
|
||||
self.profile_printer = params['profile_printer'] if params.get('profile_printer') else 'TM-P80'
|
||||
self.set_style(SCREENS[self.screen_size], _theme)
|
||||
|
||||
self.is_clear_right_panel = True
|
||||
|
@ -395,30 +395,30 @@ class MainWindow(FrontWindow):
|
|||
|
||||
def create_dialogs(self):
|
||||
# self.create_wizard_new_sale()
|
||||
self.dialog_search_products = SearchProduct(self)
|
||||
self.dialog_position = Position(self, 'action')
|
||||
self.dialog_comment = Comment(self, 'action')
|
||||
self.dialog_search_parties = SearchParty(self)
|
||||
self.dialog_payment = DialogPayment(self, 'selection')
|
||||
self.dialog_salesman = DialogSalesman(self, 'selection')
|
||||
self.dialog_voucher = DialogVoucher(self, 'action')
|
||||
self.dialog_print_invoice = DialogPrintInvoice(self, 'action')
|
||||
self.dialog_global_discount = DialogGlobalDiscount(self, 'action')
|
||||
self.dialog_payment_term = DialogPaymentTerm(self, 'selection')
|
||||
self.dialog_search_sales = SearchSale(self)
|
||||
self.dialog_search_sales = SearchSale(self).get()
|
||||
self.dialog_search_parties = SearchParty(self).get()
|
||||
self.dialog_search_products = SearchProduct(self).get()
|
||||
self.dialog_position = Position(self).get('action')
|
||||
self.dialog_comment = Comment(self).get('action')
|
||||
self.dialog_payment = DialogPayment(self).get('selection')
|
||||
self.dialog_salesman = DialogSalesman(self).get('selection')
|
||||
self.dialog_voucher = DialogVoucher(self).get('action')
|
||||
self.dialog_print_invoice = DialogPrintInvoice(self).get('action')
|
||||
self.dialog_global_discount = DialogGlobalDiscount(self).get('action')
|
||||
self.dialog_payment_term = DialogPaymentTerm(self).get('selection')
|
||||
self.dialog_search_sales.activate_counter()
|
||||
self.dialog_product_stock = Dialogstock(self.dialog_search_products, 'selection')
|
||||
self.dialog_order = DialogOrder(self, 'action')
|
||||
self.dialog_force_assign = DialogForceAssing(self, 'action')
|
||||
self.dialog_product_stock = DialogStock(self.dialog_search_products).get('selection')
|
||||
self.dialog_order = DialogOrder(self).get('action')
|
||||
self.dialog_force_assign = DialogForceAssign(self).get('action')
|
||||
self.field_password_force_assign_ask.setEchoMode(QLineEdit.Password)
|
||||
self.dialog_tax = DialogTaxes(self, 'selection')
|
||||
self.dialog_cancel_invoice = DialogCancelInvoice(self, 'action')
|
||||
self.dialog_product_edit = SaleLine(self, 'action')
|
||||
self.dialog_tax = DialogTaxes(self).get('selection')
|
||||
self.dialog_cancel_invoice = DialogCancelInvoice(self).get('action')
|
||||
self.dialog_product_edit = SaleLine(self).get('action')
|
||||
if self._commission_activated:
|
||||
self.dialog_agent = DialogAgent(self, 'action')
|
||||
self.dialog_agent = DialogAgent(self).get('action')
|
||||
if self.enviroment == 'restaurant' and self._sale_pos_restaurant:
|
||||
self.dialog_search_consumer = DialogConsumer(self, 'action')
|
||||
self.dialog_manage_tables = DialogManageTables(self, 'action')
|
||||
self.dialog_search_consumer = DialogConsumer(self).get('action')
|
||||
self.dialog_manage_tables = DialogManageTables(self).get('action')
|
||||
|
||||
def set_printing_context(self):
|
||||
# Printing invoice context
|
||||
|
@ -445,6 +445,7 @@ class MainWindow(FrontWindow):
|
|||
printer = {
|
||||
'interface': self.printer_sale_name[0],
|
||||
'device': self.printer_sale_name[1],
|
||||
'profile': self.profile_printer,
|
||||
}
|
||||
if printer:
|
||||
self.receipt_sale.set_printer(printer)
|
||||
|
@ -490,7 +491,7 @@ class MainWindow(FrontWindow):
|
|||
_label_type_invoice.setObjectName('label_invoice')
|
||||
_label_type_invoice.setAlignment(alignRight | alignVCenter)
|
||||
|
||||
self.field_amount = FieldMoney(self, 'amount', {})
|
||||
self.field_amount = FieldNumeric(self, 'amount', {})
|
||||
self.field_amount.setObjectName('field_amount')
|
||||
self.field_sign = QLabel(' ')
|
||||
self.field_sign.setObjectName('field_sign')
|
||||
|
@ -1011,6 +1012,7 @@ class MainWindow(FrontWindow):
|
|||
if not sale_id:
|
||||
sale_id = self._sale['id']
|
||||
data = self._PosSale.get_data(sale_id, self._context)
|
||||
print(data['qr_code'])
|
||||
for i in range(copies):
|
||||
self.receipt_sale.print_sale(data)
|
||||
|
||||
|
@ -1760,6 +1762,7 @@ class MainWindow(FrontWindow):
|
|||
self.dialog_search_consumer.clear_dialog()
|
||||
self.check_empty_sale()
|
||||
if self.type_pos_user == 'cashier':
|
||||
self.message_bar.set('not_sale')
|
||||
self.state_disabled()
|
||||
return
|
||||
self.set_state('add')
|
||||
|
@ -2264,13 +2267,158 @@ class MainWindow(FrontWindow):
|
|||
self.action_comment()
|
||||
elif key == Qt.Key_Question:
|
||||
self.action_tax()
|
||||
sale = self.get_current_sale()
|
||||
self.field_state.setText(sale['state'])
|
||||
|
||||
@property
|
||||
def state(self):
|
||||
return self._state
|
||||
|
||||
def update_sale_line(self, field):
|
||||
value = None
|
||||
self.state_line['id'] = self._current_line_id
|
||||
if field == 'quantity':
|
||||
value = Decimal(self.row_field_qty.value())
|
||||
if field == 'unit_price':
|
||||
value = self.row_field_price.text()
|
||||
if field == 'qty_fraction':
|
||||
qty = self.field_combobox_fraction.get_id()
|
||||
self.row_field_qty.setValue(float(qty))
|
||||
value = self.field_combobox_fraction.get_label()
|
||||
self.state_line['quantity'] = qty
|
||||
price_ = self.ModSale.get_product_prices({
|
||||
'ids': [self._sale_line['product']['id']],
|
||||
'quantity': float(qty),
|
||||
'sale_id': self._sale['id'],
|
||||
})
|
||||
if price_ and price_.get('unit_price_w_tax'):
|
||||
price_list = str(price_['unit_price_w_tax'])
|
||||
self.row_field_price.setText(price_list)
|
||||
self.state_line['unit_price'] = price_list
|
||||
|
||||
if field == 'description':
|
||||
value = self.row_field_description.text()
|
||||
if field == 'note':
|
||||
value = self.row_field_note.toPlainText()
|
||||
|
||||
if value:
|
||||
self.state_line[field] = value
|
||||
|
||||
def dialog_product_edit_accepted(self):
|
||||
if not self.state_line:
|
||||
return
|
||||
|
||||
_record = None
|
||||
|
||||
if self.state_line.get('quantity'):
|
||||
quantity = self.state_line.pop('quantity')
|
||||
_record = self.ModSaleLine.faster_set_quantity({
|
||||
'id': self._current_line_id,
|
||||
'quantity': to_float(quantity, 2)
|
||||
})
|
||||
|
||||
if self.state_line.get('unit_price'):
|
||||
unit_price = self.state_line.pop('unit_price')
|
||||
self._sign = '/'
|
||||
self._process_price(unit_price)
|
||||
self._sign = None
|
||||
_record = self.ModSaleLine.write([self._current_line_id], {})
|
||||
|
||||
if self.state_line.get('description'):
|
||||
_record = self.ModSaleLine.write([self._current_line_id], {
|
||||
'description': self.state_line['description']
|
||||
})
|
||||
|
||||
if self.state_line.get('note'):
|
||||
_record = self.ModSaleLine.write([self._current_line_id], {
|
||||
'note': self.state_line['note']
|
||||
})
|
||||
|
||||
if _record:
|
||||
if not _record.get('unit.symbol'):
|
||||
_record['unit.symbol'] = _record['unit']['symbol']
|
||||
if not _record.get('product.template.name'):
|
||||
_record['product.template.name'] = _record['product']['template']['name']
|
||||
if not _record.get('product.code'):
|
||||
_record['product.code'] = _record['product']['code']
|
||||
self.model_sale_lines.update_record(_record)
|
||||
|
||||
self.update_total_amount()
|
||||
self.state_line = {}
|
||||
|
||||
def dialog_search_consumer_accepted(self):
|
||||
if not self.state_consumer:
|
||||
return
|
||||
if self._consumer:
|
||||
res = self.ModSale.update_consumer({
|
||||
'id': self._consumer['id'],
|
||||
'fields': self.state_consumer,
|
||||
})
|
||||
if res['msg'] != 'ok':
|
||||
print('error')
|
||||
else:
|
||||
res = self.ModSale.create_consumer({
|
||||
'fields': self.state_consumer,
|
||||
})
|
||||
if res['msg'] != 'ok':
|
||||
print('error')
|
||||
|
||||
def update_consumer_data(self, field=''):
|
||||
if field == 'address':
|
||||
self.state_consumer['address'] = self.row_field_address.text()
|
||||
elif field == 'id_number':
|
||||
self.state_consumer['id_number'] = self.row_field_id_number.text()
|
||||
elif field == 'name':
|
||||
self.state_consumer['name'] = self.row_field_consumer.text()
|
||||
elif field == 'birthday':
|
||||
self.state_consumer['birthday'] = self.row_field_birthday.date().toPyDate()
|
||||
elif field == 'phone':
|
||||
self._text_field_phone = self.row_field_phone.text()
|
||||
if self._text_field_phone:
|
||||
self.state_consumer['phone'] = self._text_field_phone
|
||||
consumers = self.PartyConsumer.find([
|
||||
('phone', '=', self._text_field_phone),
|
||||
])
|
||||
if not consumers:
|
||||
self._consumer = {}
|
||||
self.row_field_address.setText('')
|
||||
self.row_field_consumer.setText('')
|
||||
self.row_field_id_number.setText('')
|
||||
self.row_field_birthday.setDate()
|
||||
else:
|
||||
self._consumer = consumers[0]
|
||||
self.row_field_address.setText(self._consumer['address'])
|
||||
self.row_field_consumer.setText(self._consumer['name'])
|
||||
self.row_field_id_number.setText(self._consumer['id_number'])
|
||||
if self._consumer.get('birthday'):
|
||||
y, m, d = self._consumer['birthday'].split('-')
|
||||
self.row_field_birthday.setDate(QDate(int(y), int(m), int(d)))
|
||||
|
||||
|
||||
def action_table_assigned(self, id, name, prev_state, new_state):
|
||||
table_assigned = id
|
||||
|
||||
if self._sale.get('table_assigned') != id and prev_state == 'occupied':
|
||||
return False
|
||||
|
||||
if self._sale.get('table_assigned') == id and new_state == 'available':
|
||||
name = ''
|
||||
table_assigned = None
|
||||
|
||||
self._sale['table_assigned'] = table_assigned
|
||||
self._sale['table_assigned.state'] = new_state
|
||||
|
||||
self._Tables.write([id], {'state': new_state})
|
||||
|
||||
self._PosSale.write([self._sale['id']], {'table_assigned': table_assigned})
|
||||
self.field_table_assigned.setText(name)
|
||||
return True
|
||||
|
||||
def clear_dialog(self):
|
||||
self.row_field_phone.setText('')
|
||||
self.row_field_address.setText('')
|
||||
self.row_field_consumer.setText('')
|
||||
self.row_field_id_number.setText('')
|
||||
# self.row_field_birthday.setDate(QDate.currentDate())
|
||||
|
||||
# def print_equivalent_invoice(self, sale_id):
|
||||
# sale, = self.ModSale.find([('id', '=', sale_id)])
|
||||
|
||||
|
|
|
@ -14,11 +14,12 @@ try:
|
|||
except:
|
||||
logging.warning("Pyudev module not found!")
|
||||
|
||||
try:
|
||||
if 1:
|
||||
from escpos import printer
|
||||
except:
|
||||
logging.warning("Escpos module not found!")
|
||||
|
||||
# from escpos.printer import File
|
||||
# except:
|
||||
# logging.warning("Escpos module not found!")
|
||||
# from escpos.printer import File
|
||||
try:
|
||||
import cups
|
||||
except:
|
||||
|
@ -125,7 +126,7 @@ class Receipt(object):
|
|||
def test_printer(self):
|
||||
if self._interface == 'usb':
|
||||
if os.name == 'posix':
|
||||
self._printer = printer.File(self._device)
|
||||
self._printer = printer.File(self._device, profile=self._profile)
|
||||
elif os.name == 'nt':
|
||||
self._printer = printer.UsbWin(self._device)
|
||||
self._printer.open()
|
||||
|
@ -136,16 +137,15 @@ class Receipt(object):
|
|||
self._printer.open()
|
||||
if not self._printer:
|
||||
return
|
||||
if self._img_logo:
|
||||
self.print_logo()
|
||||
self.print_enter()
|
||||
self._printer.image('image_test.jpeg', center=True)
|
||||
self.print_enter()
|
||||
self.print_header()
|
||||
self.print_enter()
|
||||
self.print_enter()
|
||||
self.print_enter()
|
||||
self._printer.cut()
|
||||
self._printer.cashdraw(2)
|
||||
self._printer.close()
|
||||
|
||||
def set_printer(self, printer):
|
||||
if dev_printers.get(printer['device']):
|
||||
|
@ -155,12 +155,13 @@ class Receipt(object):
|
|||
|
||||
self._interface = printer['interface']
|
||||
self._device = device
|
||||
self._profile = printer['profile']
|
||||
|
||||
def print_sale(self, sale):
|
||||
try:
|
||||
if self._interface == 'usb':
|
||||
if os.name == 'posix':
|
||||
self._printer = printer.File(self._device)
|
||||
self._printer = printer.File(self._device, profile=self._profile)
|
||||
elif os.name == 'nt':
|
||||
self._printer = printer.UsbWin(self._device)
|
||||
self._printer.open()
|
||||
|
@ -184,18 +185,25 @@ class Receipt(object):
|
|||
def _print_sale(self, sale):
|
||||
self.print_header()
|
||||
self.print_body(sale)
|
||||
if sale.get('cufe'):
|
||||
self._printer.text('CUFE: ' + sale['cufe'])
|
||||
if sale.get('qr_code'):
|
||||
self.print_qrcode(sale['qr_code'])
|
||||
self.print_footer()
|
||||
# self.print_extra_info(sale)
|
||||
if self._interface in ['usb', 'ssh', 'network']:
|
||||
self._printer.close()
|
||||
elif self._interface == 'cups':
|
||||
if self._interface == 'cups':
|
||||
self._file.close()
|
||||
self.conn.printFile(self._printer_name, TEMP_INVOICE_FILE,
|
||||
'POS Invoice', {})
|
||||
|
||||
def print_logo(self):
|
||||
self._printer.set(align='center')
|
||||
self._printer.image(self._img_logo)
|
||||
# self._printer.set(align='center')
|
||||
self._printer.image(self._img_logo, center=True)
|
||||
self.print_enter()
|
||||
|
||||
def print_qrcode(self, qrcode):
|
||||
# self._printer.set(align='center')
|
||||
self._printer.qr(qrcode, center=True, size=5)
|
||||
self.print_enter()
|
||||
|
||||
def print_header(self):
|
||||
|
@ -264,6 +272,8 @@ class Receipt(object):
|
|||
#mod_hours = sale["create_date"] + timedelta(hours=self._delta_locale)
|
||||
#time_ = mod_hours.strftime('%I:%M %p')
|
||||
self._printer.text('Fecha:%s' % sale['date'])
|
||||
if sale.get('invoice_time'):
|
||||
self._printer.text(' Hora:%s' % sale['invoice_time'])
|
||||
if sale.get('turn') and sale['turn'] != 0:
|
||||
self._printer.text('Turno: %s - ' % str(sale['turn']))
|
||||
self.print_enter()
|
||||
|
@ -472,8 +482,6 @@ class Receipt(object):
|
|||
self.print_body_order(order, reversion)
|
||||
self._printer.cut()
|
||||
self._row_characters = order['row_characters']
|
||||
if order['interface'] in ('network', 'usb', 'ssh'):
|
||||
self._printer.close()
|
||||
return True
|
||||
|
||||
def print_body_order(self, order, reversion):
|
||||
|
@ -615,10 +623,10 @@ if __name__ == '__main__':
|
|||
# Test for Escpos interface printer Linux
|
||||
|
||||
# Network example
|
||||
device = 'network', '192.168.0.32'
|
||||
# device = 'network', '192.168.0.32'
|
||||
|
||||
# Unix-like Usb example
|
||||
# device = 'usb','/dev/usb/lp1'
|
||||
device = 'usb','/dev/usb/lp1'
|
||||
|
||||
# Windows Usb example for printer nameb SATPOS
|
||||
# device = 'usb', 'SATPOS'
|
||||
|
@ -629,6 +637,7 @@ if __name__ == '__main__':
|
|||
example_dev = {
|
||||
'interface': device[0],
|
||||
'device': device[1],
|
||||
'profile': 'TM-P80',
|
||||
}
|
||||
|
||||
ctx_printing = {}
|
||||
|
|
|
@ -19,10 +19,11 @@ user=admin
|
|||
#
|
||||
##########################################
|
||||
printer_sale_name=usb,/dev/usb/lp0
|
||||
profile_printer=TM-P80
|
||||
|
||||
# ROW CHARACTERS: 33 / 48 / 28
|
||||
# --- EPSON TM-T20 = 33
|
||||
# --- TALLY DT-230 = 48
|
||||
# --- SAT 23T = 48
|
||||
# --- SAT = 42
|
||||
row_characters=48
|
||||
|
||||
|
|
2
setup.py
2
setup.py
|
@ -34,7 +34,7 @@ if os.name == 'posix':
|
|||
|
||||
|
||||
setup(name='presik_pos',
|
||||
version='5.0.2',
|
||||
version='5.0.3',
|
||||
description='POS Client for Tryton',
|
||||
author='Oscar Alvarez',
|
||||
author_email='gerente@presik.com',
|
||||
|
|
Loading…
Reference in a new issue