new release version add option debug
This commit is contained in:
parent
c9b2f22b29
commit
543385d0fa
|
@ -21,6 +21,7 @@
|
||||||
npm-debug.log*
|
npm-debug.log*
|
||||||
yarn-debug.log*
|
yarn-debug.log*
|
||||||
yarn-error.log*
|
yarn-error.log*
|
||||||
|
*.log*
|
||||||
|
|
||||||
package-lock*
|
package-lock*
|
||||||
|
|
||||||
|
|
|
@ -63,12 +63,15 @@ class StartButtons(QVBoxLayout):
|
||||||
values_extend([
|
values_extend([
|
||||||
['button_control_panel', 'PANEL DE CONTROL', 'action_control_panel', 'settings'],
|
['button_control_panel', 'PANEL DE CONTROL', 'action_control_panel', 'settings'],
|
||||||
['button_reports', 'REPORTES', 'action_reports', 'reports'],
|
['button_reports', 'REPORTES', 'action_reports', 'reports'],
|
||||||
['button_historic_sales', 'HISTORIAL', 'action_historic_sales', 'sales_history'],
|
|
||||||
])
|
])
|
||||||
if parent.environment == 'retail':
|
if parent.environment == 'retail':
|
||||||
values_extend([
|
values_extend([
|
||||||
['button_collection', 'RECAUDO', 'action_collection', 'collection']
|
['button_collection', 'RECAUDO', 'action_collection', 'collection']
|
||||||
])
|
])
|
||||||
|
else:
|
||||||
|
values_extend([
|
||||||
|
['button_historic_sales', 'HISTORIAL', 'action_historic_sales', 'sales_history'],
|
||||||
|
])
|
||||||
|
|
||||||
values_extend([
|
values_extend([
|
||||||
['button_help', 'AYUDA', 'action_help', 'help'],
|
['button_help', 'AYUDA', 'action_help', 'help'],
|
||||||
|
@ -156,7 +159,7 @@ class ButtonsFunction(QGridLayout):
|
||||||
['button_change_salesman', 'CAMBIO VENDEDOR', 'action_change_salesman'],
|
['button_change_salesman', 'CAMBIO VENDEDOR', 'action_change_salesman'],
|
||||||
])
|
])
|
||||||
pos_user = self.parent.type_pos_user
|
pos_user = self.parent.type_pos_user
|
||||||
if pos_user in ('order' ,'salesman'):
|
if pos_user in ('order', 'salesman'):
|
||||||
self.values.extend([
|
self.values.extend([
|
||||||
['button_to_draft', 'BORRADOR', 'button_to_draft_pressed'],
|
['button_to_draft', 'BORRADOR', 'button_to_draft_pressed'],
|
||||||
['button_to_quote', 'COTIZAR', 'button_to_quote_pressed'],
|
['button_to_quote', 'COTIZAR', 'button_to_quote_pressed'],
|
||||||
|
|
|
@ -6,9 +6,8 @@ import gettext
|
||||||
import logging
|
import logging
|
||||||
import time
|
import time
|
||||||
import ssl
|
import ssl
|
||||||
from collections import OrderedDict
|
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
from PySide6.QtWidgets import (QMainWindow, QDialog)
|
from PySide6.QtWidgets import QDialog
|
||||||
from PySide6.QtCore import Qt, QTimer
|
from PySide6.QtCore import Qt, QTimer
|
||||||
from PySide6.QtGui import QPixmap
|
from PySide6.QtGui import QPixmap
|
||||||
from http.client import HTTPConnection, HTTPSConnection
|
from http.client import HTTPConnection, HTTPSConnection
|
||||||
|
@ -16,6 +15,7 @@ import orjson as json
|
||||||
from app.threads import VerifyConn
|
from app.threads import VerifyConn
|
||||||
from app.commons.config import Params
|
from app.commons.config import Params
|
||||||
from app.commons.ui_login import Ui_Login
|
from app.commons.ui_login import Ui_Login
|
||||||
|
from logger_config import logger
|
||||||
context_http = ssl._create_unverified_context()
|
context_http = ssl._create_unverified_context()
|
||||||
|
|
||||||
_ = gettext.gettext
|
_ = gettext.gettext
|
||||||
|
@ -57,8 +57,7 @@ class Login(QDialog):
|
||||||
conn.close()
|
conn.close()
|
||||||
option = u"online"
|
option = u"online"
|
||||||
icon_conn = path_circle_green
|
icon_conn = path_circle_green
|
||||||
except Exception as e:
|
except Exception:
|
||||||
print(e, 'error')
|
|
||||||
icon_conn = path_circle_red
|
icon_conn = path_circle_red
|
||||||
option = u"offline"
|
option = u"offline"
|
||||||
self.ui.label_conn.setText(option)
|
self.ui.label_conn.setText(option)
|
||||||
|
@ -135,7 +134,8 @@ class Login(QDialog):
|
||||||
msg = 'Error: conexion del servidor'
|
msg = 'Error: conexion del servidor'
|
||||||
elif result['status'] == 500:
|
elif result['status'] == 500:
|
||||||
msg = 'Error: interno del servidor \n' + result['message']
|
msg = 'Error: interno del servidor \n' + result['message']
|
||||||
print(msg, 'msg ,,,,', result['status'])
|
logger.error(result)
|
||||||
|
logger.info(msg)
|
||||||
self.ui.label_error.setText(msg)
|
self.ui.label_error.setText(msg)
|
||||||
self.error_message()
|
self.error_message()
|
||||||
else:
|
else:
|
||||||
|
|
|
@ -7,7 +7,6 @@ from collections import OrderedDict
|
||||||
# )
|
# )
|
||||||
# from PyQt5.QtGui import QStandardItem, QStandardItemModel, QPixmap
|
# from PyQt5.QtGui import QStandardItem, QStandardItemModel, QPixmap
|
||||||
# from PyQt5.QtCore import Qt, pyqtSlot, QModelIndex
|
# from PyQt5.QtCore import Qt, pyqtSlot, QModelIndex
|
||||||
from operator import methodcaller
|
|
||||||
from PySide6.QtWidgets import (
|
from PySide6.QtWidgets import (
|
||||||
QDialog, QAbstractItemView, QVBoxLayout, QHBoxLayout, QLabel, QWidget,
|
QDialog, QAbstractItemView, QVBoxLayout, QHBoxLayout, QLabel, QWidget,
|
||||||
QTreeView, QLineEdit, QTableView, QCompleter
|
QTreeView, QLineEdit, QTableView, QCompleter
|
||||||
|
@ -179,7 +178,7 @@ class QuickDialog(QDialog):
|
||||||
print('cancell quitdialog')
|
print('cancell quitdialog')
|
||||||
try:
|
try:
|
||||||
self.parent.label_input.setFocus()
|
self.parent.label_input.setFocus()
|
||||||
except:
|
except Exception:
|
||||||
pass
|
pass
|
||||||
self.setResult(0)
|
self.setResult(0)
|
||||||
self.hide()
|
self.hide()
|
||||||
|
|
|
@ -1,16 +1,16 @@
|
||||||
from decimal import Decimal
|
from decimal import Decimal
|
||||||
from datetime import datetime
|
from datetime import datetime
|
||||||
from operator import itemgetter, attrgetter
|
from operator import itemgetter
|
||||||
from .commons.dialogs import HelpDialog, QuickDialog
|
from .commons.dialogs import HelpDialog, QuickDialog
|
||||||
# from PyQt5.QtCore import Qt, QSize
|
# from PyQt5.QtCore import Qt, QSize
|
||||||
# from PyQt5.QtWidgets import (
|
# from PyQt5.QtWidgets import (
|
||||||
# QCheckBox, QTextEdit, QVBoxLayout, QGridLayout, QLineEdit, QPlainTextEdit,
|
# QCheckBox, QTextEdit, QVBoxLayout, QGridLayout, QLineEdit, QPlainTextEdit,
|
||||||
# QScrollArea, QHBoxLayout, QDoubleSpinBox, QLabel, QMessageBox
|
# QScrollArea, QHBoxLayout, QDoubleSpinBox, QLabel, QMessageBox
|
||||||
# )
|
# )
|
||||||
from PySide6.QtCore import Qt, QSize
|
from PySide6.QtCore import Qt
|
||||||
from PySide6.QtWidgets import (
|
from PySide6.QtWidgets import (
|
||||||
QCheckBox, QTextEdit, QVBoxLayout, QGridLayout, QLineEdit, QPlainTextEdit,
|
QCheckBox, QTextEdit, QVBoxLayout, QGridLayout, QLineEdit, QPlainTextEdit,
|
||||||
QScrollArea, QHBoxLayout, QDoubleSpinBox, QLabel, QMessageBox, QWidget
|
QScrollArea, QHBoxLayout, QDoubleSpinBox, QLabel, QWidget
|
||||||
)
|
)
|
||||||
|
|
||||||
from .proxy import Report
|
from .proxy import Report
|
||||||
|
@ -287,8 +287,8 @@ class SearchParty(SearchWindow):
|
||||||
# 'street': parent.on_selected_street_party
|
# 'street': parent.on_selected_street_party
|
||||||
}
|
}
|
||||||
super(SearchParty, self).__init__(parent, headers, None, methods,
|
super(SearchParty, self).__init__(parent, headers, None, methods,
|
||||||
filter_column=[], cols_width=[60, 120, 270, 190, 90],
|
filter_column=[], cols_width=[60, 120, 270, 190, 90],
|
||||||
title=title, fill=True)
|
title=title, fill=True)
|
||||||
|
|
||||||
|
|
||||||
class SearchProduct(SearchWindow):
|
class SearchProduct(SearchWindow):
|
||||||
|
@ -350,7 +350,7 @@ class SearchProduct(SearchWindow):
|
||||||
fields_names = list(headers.keys())
|
fields_names = list(headers.keys())
|
||||||
try:
|
try:
|
||||||
fields_names.remove('image')
|
fields_names.remove('image')
|
||||||
except:
|
except Exception:
|
||||||
pass
|
pass
|
||||||
self.fields_names = fields_names
|
self.fields_names = fields_names
|
||||||
super(SearchProduct, self).__init__(parent, headers, None, methods,
|
super(SearchProduct, self).__init__(parent, headers, None, methods,
|
||||||
|
@ -594,7 +594,7 @@ class DialogSaleForm(QuickDialog):
|
||||||
elements = (
|
elements = (
|
||||||
'id', 'party.', 'number', 'sale_date',
|
'id', 'party.', 'number', 'sale_date',
|
||||||
'total_amount_cache', 'invoice_number', 'lines.'
|
'total_amount_cache', 'invoice_number', 'lines.'
|
||||||
)
|
)
|
||||||
id, party, number, sale_date, total_amount_cache, invoice_number, lines = itemgetter(*elements)(data)
|
id, party, number, sale_date, total_amount_cache, invoice_number, lines = itemgetter(*elements)(data)
|
||||||
self.sale_customer_selected = id
|
self.sale_customer_selected = id
|
||||||
self.field_party.setText(party['name'])
|
self.field_party.setText(party['name'])
|
||||||
|
@ -887,7 +887,7 @@ class DialogTableDeliveryParty(QuickDialog):
|
||||||
method_selected_row=parent.delivery_party_selected
|
method_selected_row=parent.delivery_party_selected
|
||||||
)
|
)
|
||||||
width, height = get_screen()
|
width, height = get_screen()
|
||||||
table.setFixedSize(int(width/2.2), int(height/2.2))
|
table.setFixedSize(int(width / 2.2), int(height / 2.2))
|
||||||
vbox_ = QVBoxLayout()
|
vbox_ = QVBoxLayout()
|
||||||
|
|
||||||
grid = QGridLayout()
|
grid = QGridLayout()
|
||||||
|
@ -923,7 +923,7 @@ class DialogMoneyCount(QuickDialog):
|
||||||
grid = QGridLayout()
|
grid = QGridLayout()
|
||||||
_sizes = (160, 120, 240)
|
_sizes = (160, 120, 240)
|
||||||
fields = (
|
fields = (
|
||||||
{'label': 'MONEDA', 'type': 'integer', 'readonly': True},
|
{'label': 'MONEDA', 'type': 'integer', 'readonly': True},
|
||||||
{'label': 'CANTIDAD', 'type': 'integer', 'change': 'set_total'},
|
{'label': 'CANTIDAD', 'type': 'integer', 'change': 'set_total'},
|
||||||
{'label': 'SUBTOTAL', 'type': 'integer', 'readonly': True},
|
{'label': 'SUBTOTAL', 'type': 'integer', 'readonly': True},
|
||||||
)
|
)
|
||||||
|
@ -1029,8 +1029,8 @@ class DialogExpenses(QuickDialog):
|
||||||
|
|
||||||
_sizes = (140, 290, 210, 150)
|
_sizes = (140, 290, 210, 150)
|
||||||
fields = (
|
fields = (
|
||||||
{'name': 'id', 'label': 'ID', 'type': 'integer', 'invisible': True},
|
{'name': 'id', 'label': 'ID', 'type': 'integer', 'invisible': True},
|
||||||
{'name': 'invoice_number', 'label': 'FACTURA', 'type': 'char'},
|
{'name': 'invoice_number', 'label': 'FACTURA', 'type': 'char'},
|
||||||
{'name': 'description', 'label': 'DESCRIPCION', 'type': 'char'},
|
{'name': 'description', 'label': 'DESCRIPCION', 'type': 'char'},
|
||||||
{'name': 'reference', 'label': 'REFERENCIA', 'type': 'char'},
|
{'name': 'reference', 'label': 'REFERENCIA', 'type': 'char'},
|
||||||
{'name': 'amount', 'label': 'VALOR', 'type': 'float', 'change': 'set_total'},
|
{'name': 'amount', 'label': 'VALOR', 'type': 'float', 'change': 'set_total'},
|
||||||
|
@ -1126,7 +1126,7 @@ class DialogTaxes(QuickDialog):
|
||||||
'heads': ['ID', 'VALOR'],
|
'heads': ['ID', 'VALOR'],
|
||||||
}
|
}
|
||||||
string = 'ESCOJA EL IMPUESTO'
|
string = 'ESCOJA EL IMPUESTO'
|
||||||
super(DialogTaxes, self).__init__(parent, 'selection', string, data)
|
super(DialogTaxes, self).__init__(parent, 'selection', string, data)
|
||||||
|
|
||||||
|
|
||||||
class DialogSource(QuickDialog):
|
class DialogSource(QuickDialog):
|
||||||
|
@ -1485,7 +1485,7 @@ class DialogComboProduct(QuickDialog):
|
||||||
self.label_qty_min = QLabel('CANT. MIN.')
|
self.label_qty_min = QLabel('CANT. MIN.')
|
||||||
self.label_qty_min.setObjectName('label_qty_min')
|
self.label_qty_min.setObjectName('label_qty_min')
|
||||||
self.hbox.addWidget(self.label_qty_min)
|
self.hbox.addWidget(self.label_qty_min)
|
||||||
|
|
||||||
self.label_qty_min_req = QLabel("")
|
self.label_qty_min_req = QLabel("")
|
||||||
self.label_qty_min_req.setObjectName('label_qty_min_req')
|
self.label_qty_min_req.setObjectName('label_qty_min_req')
|
||||||
self.hbox.addWidget(self.label_qty_min_req)
|
self.hbox.addWidget(self.label_qty_min_req)
|
||||||
|
@ -1609,7 +1609,8 @@ class Help(HelpDialog):
|
||||||
('DOMICILIARIO', 'F12'),
|
('DOMICILIARIO', 'F12'),
|
||||||
('POSICION', 'Insert'),
|
('POSICION', 'Insert'),
|
||||||
('FACTURAR', 'End'),
|
('FACTURAR', 'End'),
|
||||||
('COMENTARIO', 'Quotation Marks'),
|
('COMENTARIO', 'COMILLAS DOBLE (")'),
|
||||||
|
('AGENTE', 'PUNTO Y COMA (;)'),
|
||||||
)
|
)
|
||||||
|
|
||||||
self.set_shortcuts(shortcuts)
|
self.set_shortcuts(shortcuts)
|
||||||
|
@ -1618,7 +1619,6 @@ class Help(HelpDialog):
|
||||||
class DialogListProduct(QuickDialog):
|
class DialogListProduct(QuickDialog):
|
||||||
def __init__(self, parent):
|
def __init__(self, parent):
|
||||||
self._parent = parent
|
self._parent = parent
|
||||||
vbox = QVBoxLayout()
|
|
||||||
grid = QGridLayout()
|
grid = QGridLayout()
|
||||||
label_code = QLabel('CODIGO:')
|
label_code = QLabel('CODIGO:')
|
||||||
label_code.setObjectName('label_info_product_code')
|
label_code.setObjectName('label_info_product_code')
|
||||||
|
@ -1806,7 +1806,7 @@ class DialogCollection(QuickDialog):
|
||||||
self.input_filter.setObjectName('input_collection_filter')
|
self.input_filter.setObjectName('input_collection_filter')
|
||||||
self.input_filter.editingFinished.connect(lambda: self.search())
|
self.input_filter.editingFinished.connect(lambda: self.search())
|
||||||
self.input_filter.returnPressed.connect(lambda: self.search())
|
self.input_filter.returnPressed.connect(lambda: self.search())
|
||||||
|
|
||||||
grid.addWidget(self.input_filter, 1, 2)
|
grid.addWidget(self.input_filter, 1, 2)
|
||||||
|
|
||||||
label_id_number = QLabel('DOCUMENTO:')
|
label_id_number = QLabel('DOCUMENTO:')
|
||||||
|
@ -1836,8 +1836,8 @@ class DialogCollection(QuickDialog):
|
||||||
label_payment_method.setObjectName('label_collection_payment_method')
|
label_payment_method.setObjectName('label_collection_payment_method')
|
||||||
grid.addWidget(label_payment_method, 5, 1)
|
grid.addWidget(label_payment_method, 5, 1)
|
||||||
self.combobox_payment_method = ComboBox(
|
self.combobox_payment_method = ComboBox(
|
||||||
parent, 'payment_method_collection', {'values': self.get_payment_methods()}
|
parent, 'payment_method_collection', {'values': self.get_payment_methods()}
|
||||||
)
|
)
|
||||||
grid.addWidget(self.combobox_payment_method, 5, 2)
|
grid.addWidget(self.combobox_payment_method, 5, 2)
|
||||||
|
|
||||||
label_voucher_number = QLabel('NUMERO COMPROBANTE:')
|
label_voucher_number = QLabel('NUMERO COMPROBANTE:')
|
||||||
|
@ -1862,8 +1862,8 @@ class DialogCollection(QuickDialog):
|
||||||
|
|
||||||
def get_payment_methods(self):
|
def get_payment_methods(self):
|
||||||
domain = [
|
domain = [
|
||||||
["sale_device", "=", self._parent.device['id']],
|
["sale_device", "=", self._parent.device['id']],
|
||||||
["state", "=", "draft"]
|
["state", "=", "draft"]
|
||||||
]
|
]
|
||||||
statements = self._parent.Statement.find(domain,
|
statements = self._parent.Statement.find(domain,
|
||||||
fields=['rec_name', 'journal.require_voucher'])
|
fields=['rec_name', 'journal.require_voucher'])
|
||||||
|
|
|
@ -3,10 +3,7 @@ import time
|
||||||
from datetime import date
|
from datetime import date
|
||||||
import logging
|
import logging
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
# from PyQt5.QtWidgets import QMainWindow, QDesktopWidget, QLineEdit
|
|
||||||
# from PyQt5.QtCore import QTimer, QThread, pyqtSignal
|
|
||||||
from PySide6.QtWidgets import QMainWindow, QLineEdit
|
from PySide6.QtWidgets import QMainWindow, QLineEdit
|
||||||
from PySide6.QtCore import QTimer, QThread, Signal
|
|
||||||
from PySide6.QtGui import QGuiApplication
|
from PySide6.QtGui import QGuiApplication
|
||||||
from .commons.dialogs import QuickDialog
|
from .commons.dialogs import QuickDialog
|
||||||
# from .commons.dblogin import safe_reconnect
|
# from .commons.dblogin import safe_reconnect
|
||||||
|
@ -29,11 +26,12 @@ from .constants import DIALOG_REPLY_YES
|
||||||
from .version import __version__
|
from .version import __version__
|
||||||
|
|
||||||
|
|
||||||
__all__ = ['FrontWindow', 'ClearUi']
|
__all__ = ['FrontWindow']
|
||||||
parent = Path(__file__).parent
|
parent = Path(__file__).parent
|
||||||
|
|
||||||
file_base_css = os.path.join(str(parent), 'css', 'base.css')
|
file_base_css = os.path.join(str(parent), 'css', 'base.css')
|
||||||
_DEFAULT_TIMEOUT = 60000 # on ms (100 minutes)
|
_DEFAULT_TIMEOUT = 60000 # on ms (100 minutes)
|
||||||
|
logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
|
||||||
class FrontWindow(QMainWindow):
|
class FrontWindow(QMainWindow):
|
||||||
|
@ -50,7 +48,6 @@ class FrontWindow(QMainWindow):
|
||||||
# self.conn = connection
|
# self.conn = connection
|
||||||
self.version = __version__
|
self.version = __version__
|
||||||
self.set_params(params)
|
self.set_params(params)
|
||||||
self.logger = logging.getLogger('app_logger')
|
|
||||||
|
|
||||||
"""
|
"""
|
||||||
We need get the size of screen (display)
|
We need get the size of screen (display)
|
||||||
|
@ -201,6 +198,14 @@ class FrontWindow(QMainWindow):
|
||||||
self._sale_pos_restaurant = None
|
self._sale_pos_restaurant = None
|
||||||
time1 = time.time()
|
time1 = time.time()
|
||||||
self.Module = Model('ir.module', self.ctx, main_window=self)
|
self.Module = Model('ir.module', self.ctx, main_window=self)
|
||||||
|
module_names = [
|
||||||
|
'sale_pos_frontend_rest', 'sale_pos',
|
||||||
|
'sale_pos_frontend', 'account_credit_limit']
|
||||||
|
modules = self.Module.find([
|
||||||
|
('name', 'in', module_names),
|
||||||
|
('state', '=', 'activated'),
|
||||||
|
])
|
||||||
|
self.modules = {m['name']: m for m in modules}
|
||||||
print(time.time() - time1, 'final')
|
print(time.time() - time1, 'final')
|
||||||
self.Config = Model('sale.configuration', self.ctx, main_window=self)
|
self.Config = Model('sale.configuration', self.ctx, main_window=self)
|
||||||
self.Sale = Model('sale.sale', self.ctx, main_window=self)
|
self.Sale = Model('sale.sale', self.ctx, main_window=self)
|
||||||
|
@ -228,10 +233,7 @@ class FrontWindow(QMainWindow):
|
||||||
self.sale_automatic = True
|
self.sale_automatic = True
|
||||||
res = self.Sale.fields_get(['commission'])
|
res = self.Sale.fields_get(['commission'])
|
||||||
self._commission_activated = True if res.get('commission') else False
|
self._commission_activated = True if res.get('commission') else False
|
||||||
self._credit_limit_activated = self.Module.find([
|
self._credit_limit_activated = 'account_credit_limit' in self.modules
|
||||||
('name', '=', 'account_credit_limit'),
|
|
||||||
('state', '=', 'activated'),
|
|
||||||
])
|
|
||||||
|
|
||||||
# _product = {
|
# _product = {
|
||||||
# 'name': 'product.product',
|
# 'name': 'product.product',
|
||||||
|
@ -340,20 +342,13 @@ class FrontWindow(QMainWindow):
|
||||||
self._password_admin = self._config.get('password_admin_pos')
|
self._password_admin = self._config.get('password_admin_pos')
|
||||||
self._password_force_assign = self._config.get('password_force_assign')
|
self._password_force_assign = self._config.get('password_force_assign')
|
||||||
if self.environment == 'restaurant':
|
if self.environment == 'restaurant':
|
||||||
self._sale_pos_restaurant = self.Module.find([
|
self._sale_pos_restaurant = 'sale_pos_frontend_rest' in self.modules
|
||||||
('name', '=', 'sale_pos_frontend_rest'),
|
print(self._sale_pos_restaurant, 'validate rest')
|
||||||
('state', '=', 'activated'),
|
|
||||||
])
|
|
||||||
if self._sale_pos_restaurant:
|
if self._sale_pos_restaurant:
|
||||||
self.RestTables = Model('sale.shop.table', self.ctx, main_window=self)
|
self.RestTables = Model('sale.shop.table', self.ctx, main_window=self)
|
||||||
self.Consumer = Model('party.consumer', self.ctx, main_window=self)
|
self.Consumer = Model('party.consumer', self.ctx, main_window=self)
|
||||||
# TODO get product and printers
|
self.printers_shop, self.products_printers = self.Sale.get_product_printers(
|
||||||
self.printers_shop, self.products_printers = None, None
|
self.shop['id'])
|
||||||
try:
|
|
||||||
self.printers_shop, self.products_printers = self.Sale.get_product_printers(
|
|
||||||
self.shop['id'])
|
|
||||||
except Exception:
|
|
||||||
pass
|
|
||||||
|
|
||||||
self._action_report_invoice, = self.ActionReport.find([
|
self._action_report_invoice, = self.ActionReport.find([
|
||||||
('report_name', '=', 'account.invoice'),
|
('report_name', '=', 'account.invoice'),
|
||||||
|
@ -374,17 +369,3 @@ class FrontWindow(QMainWindow):
|
||||||
self.Source = Model('sale.source', self.ctx, main_window=self)
|
self.Source = Model('sale.source', self.ctx, main_window=self)
|
||||||
self.Pricelist = Model('product.price_list', self.ctx, main_window=self)
|
self.Pricelist = Model('product.price_list', self.ctx, main_window=self)
|
||||||
return True
|
return True
|
||||||
|
|
||||||
|
|
||||||
class ClearUi(QThread):
|
|
||||||
# sigActionClear = pyqtSignal()
|
|
||||||
sigActionClear = Signal()
|
|
||||||
state = None
|
|
||||||
|
|
||||||
def __init__(self, wait_time):
|
|
||||||
QThread.__init__(self)
|
|
||||||
self.wait_time = wait_time
|
|
||||||
|
|
||||||
def run(self):
|
|
||||||
time.sleep(self.wait_time)
|
|
||||||
self.sigActionClear.emit()
|
|
||||||
|
|
238
app/main.py
238
app/main.py
|
@ -7,7 +7,7 @@ import base64
|
||||||
import time
|
import time
|
||||||
import traceback
|
import traceback
|
||||||
from decimal import Decimal
|
from decimal import Decimal
|
||||||
from datetime import datetime, timedelta, date
|
from datetime import datetime, timedelta
|
||||||
from collections import OrderedDict
|
from collections import OrderedDict
|
||||||
from PySide6 import QtGui
|
from PySide6 import QtGui
|
||||||
from PySide6.QtCore import Qt, QTimer
|
from PySide6.QtCore import Qt, QTimer
|
||||||
|
@ -16,7 +16,7 @@ from PySide6.QtWidgets import (
|
||||||
QWidget)
|
QWidget)
|
||||||
from app.commons.image import Image
|
from app.commons.image import Image
|
||||||
from .frontwindow import FrontWindow
|
from .frontwindow import FrontWindow
|
||||||
from .tools import get_icon, to_float, to_numeric
|
from .tools import get_icon, to_float, to_numeric, compare_versions
|
||||||
from .status_bar import StatusBar
|
from .status_bar import StatusBar
|
||||||
from .stack_messages import StackMessages
|
from .stack_messages import StackMessages
|
||||||
# from app.commons.action import Action
|
# from app.commons.action import Action
|
||||||
|
@ -31,7 +31,7 @@ from .proxy import Report
|
||||||
from .buttonpad import ButtonsStacked, ButtonsFunction, StartButtons
|
from .buttonpad import ButtonsStacked, ButtonsFunction, StartButtons
|
||||||
from .states import STATES, RE_SIGN
|
from .states import STATES, RE_SIGN
|
||||||
from .commons.custom_button import CustomButton
|
from .commons.custom_button import CustomButton
|
||||||
from .threads import DoInvoice, VerifyOrderCommand
|
from .threads import DoInvoice
|
||||||
from .store import StoreView
|
from .store import StoreView
|
||||||
from .constants import (
|
from .constants import (
|
||||||
PATH_PRINTERS, DELTA_LOCALE, STRETCH, alignRight, alignLeft, alignCenter,
|
PATH_PRINTERS, DELTA_LOCALE, STRETCH, alignRight, alignLeft, alignCenter,
|
||||||
|
@ -76,7 +76,8 @@ class AppWindow(FrontWindow):
|
||||||
return
|
return
|
||||||
self.setup_sale_line()
|
self.setup_sale_line()
|
||||||
self.setup_delivery_party()
|
self.setup_delivery_party()
|
||||||
self.setup_sale_consumer()
|
if self.environment == 'restaurant':
|
||||||
|
self.setup_sale_consumer()
|
||||||
self.setup_payment()
|
self.setup_payment()
|
||||||
# self.set_domains()
|
# self.set_domains()
|
||||||
print(time.time() - time1, 'set domains')
|
print(time.time() - time1, 'set domains')
|
||||||
|
@ -106,19 +107,16 @@ class AppWindow(FrontWindow):
|
||||||
self.reader_thread = ScaleReader()
|
self.reader_thread = ScaleReader()
|
||||||
self.reader_thread.sigSetWeight.connect(self.set_weight_readed)
|
self.reader_thread.sigSetWeight.connect(self.set_weight_readed)
|
||||||
|
|
||||||
if self.server_printer:
|
if self.server_printer and self.environment == 'restaurant':
|
||||||
self.verify_command_order_th = VerifyOrderCommand(self)
|
timer = QTimer()
|
||||||
self.verify_command_order_th.sigVerifyOrderCommand.connect(self.verify_print_order_automatic)
|
timer.timeout.connect(self.verify_print_order_automatic)
|
||||||
self.verify_command_order_th.start()
|
timer.start(30000)
|
||||||
|
|
||||||
self.do_invoice = DoInvoice(self, self.ctx)
|
self.do_invoice = DoInvoice(self, self.ctx)
|
||||||
self.do_invoice.sigDoInvoice.connect(self.__do_invoice_thread)
|
self.do_invoice.sigDoInvoice.connect(self.__do_invoice_thread)
|
||||||
self.set_state('disabled')
|
self.set_state('disabled')
|
||||||
self.change_view_to('start_front')
|
self.change_view_to('start_front')
|
||||||
|
|
||||||
# if self.cache_local:
|
|
||||||
# self.set_cache_company()
|
|
||||||
# self.set_cache_products()
|
|
||||||
matching_journal = next((j for j in self._journals if j['id'] == self.default_journal['id']), None)
|
matching_journal = next((j for j in self._journals if j['id'] == self.default_journal['id']), None)
|
||||||
if matching_journal:
|
if matching_journal:
|
||||||
self.default_journal = matching_journal
|
self.default_journal = matching_journal
|
||||||
|
@ -136,24 +134,45 @@ class AppWindow(FrontWindow):
|
||||||
self.field_agent = None
|
self.field_agent = None
|
||||||
|
|
||||||
def verify_print_order_automatic(self):
|
def verify_print_order_automatic(self):
|
||||||
records = self.Sale.get_orders_to_command({'shop': self.shop['id']})
|
args = {'shop': self.shop['id']}
|
||||||
for record in records:
|
orders = []
|
||||||
orders = record['orders']
|
tasks = []
|
||||||
tasks = record['tasks']
|
version = compare_versions(self.modules['sale_pos_frontend_rest']['version'], '6.0.7')
|
||||||
try:
|
if version in ('equal', 'higher'):
|
||||||
result = self.receipt_order.print_orders(orders.values())
|
print('pasa por esta new query')
|
||||||
if result:
|
if not self.tasks_station:
|
||||||
self.Sale.mark_commanded({'sale_id': record['id'], 'lines_ids': result})
|
orders = self.SaleLine.get_data_command(args)
|
||||||
receipt = Receipt(context={}, environment='restaurant')
|
else:
|
||||||
receipt.print_tasks(tasks)
|
result = self.SaleLine.get_data_command_and_task(args)
|
||||||
except Exception as e:
|
orders = result['orders']
|
||||||
print(e)
|
tasks = result['tasks']
|
||||||
traceback.print_exc()
|
|
||||||
|
|
||||||
timer = QTimer()
|
# TODO: for remove this option
|
||||||
timer.timeout.connect(self.verify_print_order_automatic)
|
else:
|
||||||
timer.start(30000)
|
records = self.Sale.get_orders_to_command(args)
|
||||||
self.verify_command_order_th.exit(0)
|
for record in records:
|
||||||
|
orders += record['orders'].values()
|
||||||
|
tasks += record['tasks'].values()
|
||||||
|
print('ingresa a impresion', orders)
|
||||||
|
print('ingresa a impresion tasks', tasks)
|
||||||
|
try:
|
||||||
|
result = self.receipt_order.print_orders(orders)
|
||||||
|
if result:
|
||||||
|
self.Sale.mark_commanded({'lines_ids': result})
|
||||||
|
except Exception:
|
||||||
|
traceback.print_exc()
|
||||||
|
|
||||||
|
try:
|
||||||
|
receipt = Receipt(context={}, environment='restaurant')
|
||||||
|
result_print = receipt.print_tasks(tasks)
|
||||||
|
if any(result_print):
|
||||||
|
print(result_print, 'validate print')
|
||||||
|
self.SaleLine.mark_tasks_printed({'task_ids': result_print})
|
||||||
|
except Exception:
|
||||||
|
traceback.print_exc()
|
||||||
|
# timer = QTimer()
|
||||||
|
# timer.singleShot(30000, self.verify_print_order_automatic)
|
||||||
|
# self.verify_command_order_th.exit(0)
|
||||||
|
|
||||||
# def set_domains(self):
|
# def set_domains(self):
|
||||||
# self.domain_search_product = [
|
# self.domain_search_product = [
|
||||||
|
@ -1745,7 +1764,7 @@ class AppWindow(FrontWindow):
|
||||||
}
|
}
|
||||||
orders, sale_number = self.Sale.get_reversion(args)
|
orders, sale_number = self.Sale.get_reversion(args)
|
||||||
self.receipt_order.print_orders(orders.values(), reversion=True)
|
self.receipt_order.print_orders(orders.values(), reversion=True)
|
||||||
except Exception as e:
|
except Exception:
|
||||||
print(self.print_order, 'validar variable en opcion print_order=True en config_pos.ini')
|
print(self.print_order, 'validar variable en opcion print_order=True en config_pos.ini')
|
||||||
logging.error('Printing order reversion fail!')
|
logging.error('Printing order reversion fail!')
|
||||||
|
|
||||||
|
@ -1823,10 +1842,11 @@ class AppWindow(FrontWindow):
|
||||||
if res == DIALOG_REPLY_NO:
|
if res == DIALOG_REPLY_NO:
|
||||||
return False
|
return False
|
||||||
result = None
|
result = None
|
||||||
if not sale.get('number'):
|
number = sale.get('number')
|
||||||
result_set = self.Sale.set_sale_number({'sale_id': sale_id})
|
if not number:
|
||||||
self.store.set({'number': result_set})
|
number = self.Sale.set_sale_number({'sale_id': sale_id})
|
||||||
self.order_number.setText(result_set)
|
self.store.set({'number': number})
|
||||||
|
self.order_number.setText(number)
|
||||||
if self.environment == 'restaurant':
|
if self.environment == 'restaurant':
|
||||||
if self.print_order:
|
if self.print_order:
|
||||||
result = self.print_command(sale)
|
result = self.print_command(sale)
|
||||||
|
@ -1842,6 +1862,7 @@ class AppWindow(FrontWindow):
|
||||||
|
|
||||||
def get_header_sale(self, sale):
|
def get_header_sale(self, sale):
|
||||||
order = {
|
order = {
|
||||||
|
'id': self.sale_id,
|
||||||
'sale_number': sale['number'],
|
'sale_number': sale['number'],
|
||||||
'number': sale.get('invoice_number'),
|
'number': sale.get('invoice_number'),
|
||||||
'turn': sale.get('turn'),
|
'turn': sale.get('turn'),
|
||||||
|
@ -1875,65 +1896,87 @@ class AppWindow(FrontWindow):
|
||||||
return result
|
return result
|
||||||
|
|
||||||
def print_command(self, sale, line_reversion=None):
|
def print_command(self, sale, line_reversion=None):
|
||||||
order = self.get_header_sale(sale)
|
version = compare_versions(self.modules['sale_pos_frontend_rest']['version'], '6.0.7')
|
||||||
reversion = False if not line_reversion else True
|
reversion = False if not line_reversion else True
|
||||||
lines = [line_reversion] if reversion else self.model_sale_lines._data
|
|
||||||
orders = {}
|
orders = {}
|
||||||
lines_ids = []
|
lines_ids = []
|
||||||
for ln in lines:
|
lines = [line_reversion] if reversion else self.model_sale_lines._data
|
||||||
if not reversion and ln['order_sended'] in (True, '✔'):
|
if version in ('equal', 'higher'):
|
||||||
continue
|
order = self.get_header_sale(sale)
|
||||||
pd_id = ln['product.']['id']
|
for ln in lines:
|
||||||
try:
|
if not reversion and ln['order_sended'] in (True, '✔'):
|
||||||
printers, cat_id = self.products_printers.get(str(pd_id))
|
continue
|
||||||
cat_id = str(cat_id[0])
|
pd_id = ln['product.']['id']
|
||||||
except Exception:
|
try:
|
||||||
traceback.print_exc()
|
printers, cat_id = self.products_printers.get(str(pd_id))
|
||||||
printers, cat_id = None, None
|
cat_id = str(cat_id[0])
|
||||||
if printers:
|
except Exception:
|
||||||
for printer_id in printers:
|
traceback.print_exc()
|
||||||
printer = self.printers_shop.get(str(printer_id))
|
printers, cat_id = None, None
|
||||||
if printer_id not in orders.keys():
|
if printers:
|
||||||
orders[printer_id] = {
|
for printer_id in printers:
|
||||||
**order,
|
printer = self.printers_shop.get(str(printer_id))
|
||||||
**printer,
|
if printer_id not in orders.keys():
|
||||||
'lines_ids': []
|
orders[printer_id] = {
|
||||||
|
**order,
|
||||||
|
**printer,
|
||||||
|
'lines_ids': []
|
||||||
|
}
|
||||||
|
if printer.get('categories'):
|
||||||
|
orders[printer_id]['lines'] = {**printer['lines']}
|
||||||
|
orders[printer_id]['categories'] = {**printer['categories']}
|
||||||
|
else:
|
||||||
|
orders[printer_id]['lines'] = []
|
||||||
|
value_line = {
|
||||||
|
'name': ln['product.']['name'],
|
||||||
|
'quantity': str(ln['quantity']),
|
||||||
|
'sale_price_taxed': '',
|
||||||
|
'amount_w_tax': ln['amount_w_tax'],
|
||||||
|
'note': ln['note']
|
||||||
}
|
}
|
||||||
if printer.get('categories'):
|
if isinstance(orders[printer_id]['lines'], list):
|
||||||
orders[printer_id]['lines'] = {**printer['lines']}
|
orders[printer_id]['lines'].append(value_line)
|
||||||
orders[printer_id]['categories'] = {**printer['categories']}
|
orders[printer_id]['lines_ids'].append(ln['id'])
|
||||||
else:
|
else:
|
||||||
orders[printer_id]['lines'] = []
|
try:
|
||||||
value_line = {
|
key_id = orders[printer_id]['categories'][cat_id]
|
||||||
'name': ln['product.']['name'],
|
except Exception:
|
||||||
'quantity': str(ln['quantity']),
|
if 'others' not in orders[printer_id]['lines'].keys():
|
||||||
'sale_price_taxed': '',
|
orders[printer_id]['lines']['others'] = {'name': 'OTROS', 'lines': []}
|
||||||
'amount_w_tax': ln['amount_w_tax'],
|
key_id = 'others'
|
||||||
'note': ln['note']
|
try:
|
||||||
}
|
orders[printer_id]['lines'][key_id]['lines'].append(value_line)
|
||||||
if isinstance(orders[printer_id]['lines'], list):
|
orders[printer_id]['lines_ids'].append(ln['id'])
|
||||||
orders[printer_id]['lines'].append(value_line)
|
except Exception:
|
||||||
orders[printer_id]['lines_ids'].append(ln['id'])
|
orders[printer_id]['lines'][key_id]['lines'] = [value_line]
|
||||||
else:
|
orders[printer_id]['lines_ids'].append(ln['id'])
|
||||||
try:
|
else:
|
||||||
key_id = orders[printer_id]['categories'][cat_id]
|
lines_ids.append(ln['id'])
|
||||||
except Exception:
|
else:
|
||||||
if 'others' not in orders[printer_id]['lines'].keys():
|
# for remove this code
|
||||||
orders[printer_id]['lines']['others'] = {'name': 'OTROS', 'lines':[]}
|
if reversion:
|
||||||
key_id = 'others'
|
args = {'sale_id': self.sale_id, 'sale_line_id': line_reversion['id']}
|
||||||
try:
|
orders, sale_number = self.Sale.get_reversion(args)
|
||||||
orders[printer_id]['lines'][key_id]['lines'].append(value_line)
|
|
||||||
orders[printer_id]['lines_ids'].append(ln['id'])
|
|
||||||
except Exception:
|
|
||||||
orders[printer_id]['lines'][key_id]['lines'] = [value_line]
|
|
||||||
orders[printer_id]['lines_ids'].append(ln['id'])
|
|
||||||
else:
|
else:
|
||||||
lines_ids.append(ln['id'])
|
args = {'sale_id': self.sale_id}
|
||||||
|
orders, sale_number = self.Sale.get_order2print(args)
|
||||||
|
|
||||||
if self.environment == 'restaurant' and self.tasks_station:
|
if self.environment == 'restaurant' and self.tasks_station:
|
||||||
data_station = self.Sale.method_instance('get_data_for_stations', self.sale_id)
|
if version in ('equal', 'higher'):
|
||||||
receipt = Receipt(context={}, environment='restaurant')
|
args = {
|
||||||
receipt.print_tasks(data_station)
|
'shop': self.shop['id'],
|
||||||
|
'sale_id': self.sale_id
|
||||||
|
}
|
||||||
|
tasks = self.SaleLine.get_data_tasks(args)
|
||||||
|
receipt = Receipt(context={}, environment='restaurant')
|
||||||
|
result_print = receipt.print_tasks(tasks)
|
||||||
|
if any(result_print):
|
||||||
|
self.SaleLine.mark_tasks_printed(result_print)
|
||||||
|
else:
|
||||||
|
data_station = self.Sale.method_instance('get_data_for_stations', self.sale_id)
|
||||||
|
receipt = Receipt(context={}, environment='restaurant')
|
||||||
|
receipt.print_tasks(data_station.values())
|
||||||
|
|
||||||
result = self.receipt_order.print_orders(orders.values(), reversion)
|
result = self.receipt_order.print_orders(orders.values(), reversion)
|
||||||
lines_sended = result + lines_ids
|
lines_sended = result + lines_ids
|
||||||
if not reversion and lines_sended:
|
if not reversion and lines_sended:
|
||||||
|
@ -1960,11 +2003,12 @@ class AppWindow(FrontWindow):
|
||||||
if self._ask_new_sale():
|
if self._ask_new_sale():
|
||||||
self.create_new_sale()
|
self.create_new_sale()
|
||||||
|
|
||||||
def numpad_price_clicked(self):
|
# for remove
|
||||||
code = self.label_input.text()
|
# def numpad_price_clicked(self):
|
||||||
product = self._search_product(code)
|
# code = self.label_input.text()
|
||||||
if not product:
|
# product = self._search_product(code)
|
||||||
return
|
# if not product:
|
||||||
|
# return
|
||||||
|
|
||||||
def _ask_new_sale(self):
|
def _ask_new_sale(self):
|
||||||
dialog = self.dialog('new_sale', response=True)
|
dialog = self.dialog('new_sale', response=True)
|
||||||
|
@ -2235,7 +2279,7 @@ class AppWindow(FrontWindow):
|
||||||
if sale.get('payments'):
|
if sale.get('payments'):
|
||||||
for payment in sale['payments']:
|
for payment in sale['payments']:
|
||||||
# FIXME
|
# FIXME
|
||||||
#self.table_payment_lines.record_add(payment)
|
# self.table_payment_lines.record_add(payment)
|
||||||
pass
|
pass
|
||||||
|
|
||||||
self.party_id = sale['party.']['id']
|
self.party_id = sale['party.']['id']
|
||||||
|
@ -2431,7 +2475,7 @@ class AppWindow(FrontWindow):
|
||||||
qty_text = self.dialog_combo_product.label_qty_add.text()
|
qty_text = self.dialog_combo_product.label_qty_add.text()
|
||||||
try:
|
try:
|
||||||
qty = int(qty_text) + 1
|
qty = int(qty_text) + 1
|
||||||
except:
|
except Exception:
|
||||||
qty = 1
|
qty = 1
|
||||||
self.dialog_combo_product.label_qty_add.setText(str(qty))
|
self.dialog_combo_product.label_qty_add.setText(str(qty))
|
||||||
self.on_selected_item(record, list_price)
|
self.on_selected_item(record, list_price)
|
||||||
|
@ -2557,7 +2601,7 @@ class AppWindow(FrontWindow):
|
||||||
|
|
||||||
ctx = self.stock_context
|
ctx = self.stock_context
|
||||||
if not self.stock_context:
|
if not self.stock_context:
|
||||||
ctx = {'price_list': self.shop['price_list.']['id']}
|
ctx = {'price_list': self.shop['price_list.']['id']}
|
||||||
else:
|
else:
|
||||||
ctx['price_list'] = self.shop['price_list.']['id']
|
ctx['price_list'] = self.shop['price_list.']['id']
|
||||||
fields = self.dialog_search_products.fields_names
|
fields = self.dialog_search_products.fields_names
|
||||||
|
@ -2795,14 +2839,14 @@ class AppWindow(FrontWindow):
|
||||||
('barcode', '=', code),
|
('barcode', '=', code),
|
||||||
('code', '=', code)
|
('code', '=', code)
|
||||||
])
|
])
|
||||||
|
# 'image', 'image_icon', 'write_date' fields remove from domain
|
||||||
products = self.Product.find(
|
products = self.Product.find(
|
||||||
domain,
|
domain,
|
||||||
fields=[
|
fields=[
|
||||||
'name', 'code', 'categories', 'description',
|
'name', 'code', 'categories', 'description',
|
||||||
'id', 'image', 'image_icon', 'list_price',
|
'id', 'list_price', 'quantity', 'rec_name', 'template',
|
||||||
'quantity', 'rec_name', 'template',
|
|
||||||
'extra_tax', 'template.sale_price_w_tax',
|
'extra_tax', 'template.sale_price_w_tax',
|
||||||
'template.default_uom', 'write_date'])
|
'template.default_uom'])
|
||||||
|
|
||||||
if not products or len(products) > 1:
|
if not products or len(products) > 1:
|
||||||
self.message_bar.set('product_not_found')
|
self.message_bar.set('product_not_found')
|
||||||
|
@ -2856,6 +2900,7 @@ class AppWindow(FrontWindow):
|
||||||
product_id = record['id'] if record else None
|
product_id = record['id'] if record else None
|
||||||
if not product_id and code:
|
if not product_id and code:
|
||||||
# REMOVE ME THIS OPTION IS FOR BARCODE
|
# REMOVE ME THIS OPTION IS FOR BARCODE
|
||||||
|
# product = self._search_product(code)
|
||||||
product = self._search_product(code)
|
product = self._search_product(code)
|
||||||
if product:
|
if product:
|
||||||
product_id = product['id']
|
product_id = product['id']
|
||||||
|
@ -3282,7 +3327,8 @@ class AppWindow(FrontWindow):
|
||||||
if note:
|
if note:
|
||||||
self.SaleLine.write([removed_item['id']], {'note': note})
|
self.SaleLine.write([removed_item['id']], {'note': note})
|
||||||
prd_code = removed_item['product.']['code']
|
prd_code = removed_item['product.']['code']
|
||||||
if prd_code and self._config['tip_product.']['code'] == prd_code:
|
tip_product = self._config.get('tip_product.')
|
||||||
|
if prd_code and tip_product and tip_product['code'] == prd_code:
|
||||||
self.Sale.write([self.sale_id], {'tip': None})
|
self.Sale.write([self.sale_id], {'tip': None})
|
||||||
self.SaleLine.delete([removed_item['id']])
|
self.SaleLine.delete([removed_item['id']])
|
||||||
self.set_amounts()
|
self.set_amounts()
|
||||||
|
|
|
@ -388,7 +388,6 @@ MODELS_RETAIL = {
|
||||||
'new_sale_automatic', 'show_product_image', 'delivery_product.code',
|
'new_sale_automatic', 'show_product_image', 'delivery_product.code',
|
||||||
'encoded_sale_price', 'delivery_product.list_price',
|
'encoded_sale_price', 'delivery_product.list_price',
|
||||||
'delivery_product.name', 'allow_discount_handle',
|
'delivery_product.name', 'allow_discount_handle',
|
||||||
'no_remove_commanded',
|
|
||||||
'cache_products_local', 'show_party_categories',
|
'cache_products_local', 'show_party_categories',
|
||||||
'print_lines_product', 'uvt_pos'
|
'print_lines_product', 'uvt_pos'
|
||||||
]
|
]
|
||||||
|
|
134
app/reporting.py
134
app/reporting.py
|
@ -8,7 +8,6 @@ from datetime import datetime
|
||||||
from decimal import Decimal
|
from decimal import Decimal
|
||||||
import subprocess
|
import subprocess
|
||||||
import time
|
import time
|
||||||
|
|
||||||
from .printing.protocols import FileSSH
|
from .printing.protocols import FileSSH
|
||||||
|
|
||||||
try:
|
try:
|
||||||
|
@ -77,7 +76,6 @@ class Receipt(object):
|
||||||
__name__ = 'frontend_pos.ticket'
|
__name__ = 'frontend_pos.ticket'
|
||||||
|
|
||||||
def __init__(self, context={}, row_characters=None, logo=None, environment='retail'):
|
def __init__(self, context={}, row_characters=None, logo=None, environment='retail'):
|
||||||
self.logger = logging.getLogger('reporting')
|
|
||||||
self._company = context.get('company')
|
self._company = context.get('company')
|
||||||
self._sale_device = context.get('sale_device')
|
self._sale_device = context.get('sale_device')
|
||||||
self._shop = context.get('shop')
|
self._shop = context.get('shop')
|
||||||
|
@ -217,18 +215,16 @@ class Receipt(object):
|
||||||
except Exception:
|
except Exception:
|
||||||
host, port = self._device, None
|
host, port = self._device, None
|
||||||
if port:
|
if port:
|
||||||
self._printer = printer.Network(host, port=int(port), timeout=15)
|
self._printer = printer.Network(host, port=int(port), timeout=5)
|
||||||
else:
|
else:
|
||||||
self._printer = printer.Network(host, timeout=15)
|
self._printer = printer.Network(host, timeout=5)
|
||||||
if not self._printer:
|
if not self._printer:
|
||||||
msg = "Warning: Can not found Printer!"
|
msg = "Warning: Can not found Printer!"
|
||||||
self.logger.info("Warning: Can not found Printer!")
|
logging.info("Warning: Can not found Printer!")
|
||||||
return msg
|
return msg
|
||||||
self.logger.info("Info: Printer is OK!")
|
except Exception:
|
||||||
except Exception as e:
|
logging.exception(
|
||||||
traceback.print_exc()
|
"Warning: Printer error or device not found!")
|
||||||
self.logger.info(
|
|
||||||
"Warning: Printer error or device not found!", str(e))
|
|
||||||
|
|
||||||
def print_sale(self, sale, type_doc=None, open_box=False):
|
def print_sale(self, sale, type_doc=None, open_box=False):
|
||||||
try:
|
try:
|
||||||
|
@ -236,33 +232,6 @@ class Receipt(object):
|
||||||
msg = self.set_printer()
|
msg = self.set_printer()
|
||||||
if msg:
|
if msg:
|
||||||
return {"error": msg}
|
return {"error": msg}
|
||||||
# if self._interface == 'usb':
|
|
||||||
# if OS_NAME == 'posix':
|
|
||||||
# self._printer = printer.File(
|
|
||||||
# self._device, profile=self._profile)
|
|
||||||
# elif OS_NAME == 'nt':
|
|
||||||
# self._printer = printer.Win32Raw(self._device)
|
|
||||||
# self._printer.open()
|
|
||||||
# elif self._interface == 'network':
|
|
||||||
# try:
|
|
||||||
# host, port = self._device.split(":")
|
|
||||||
# except:
|
|
||||||
# host, port = self._device, None
|
|
||||||
# if port:
|
|
||||||
# self._printer = printer.Network(host, port=int(port), timeout=15)
|
|
||||||
# else:
|
|
||||||
# self._printer = printer.Network(host, timeout=15)
|
|
||||||
# elif self._interface == 'ssh':
|
|
||||||
# self._printer = FileSSH(*self._device.split('@'))
|
|
||||||
# self._printer.open()
|
|
||||||
# elif self._interface == 'cups':
|
|
||||||
# self.conn = cups.Connection()
|
|
||||||
# self._file = open(TEMP_INVOICE_FILE, 'w')
|
|
||||||
# self._printer = CupsPrinter(self._file, self._row_characters)
|
|
||||||
# if not self._printer:
|
|
||||||
# self.logger.info("Warning: Can not found Printer!")
|
|
||||||
# return
|
|
||||||
# self.logger.info("Info: Printer is OK!")
|
|
||||||
try:
|
try:
|
||||||
if type_doc in ('invoice', 'quotation') or self._environment == 'retail':
|
if type_doc in ('invoice', 'quotation') or self._environment == 'retail':
|
||||||
self._print_sale(sale, type_doc, open_box)
|
self._print_sale(sale, type_doc, open_box)
|
||||||
|
@ -271,9 +240,8 @@ class Receipt(object):
|
||||||
except Exception:
|
except Exception:
|
||||||
pass
|
pass
|
||||||
self._printer.close()
|
self._printer.close()
|
||||||
except Exception as e:
|
except Exception:
|
||||||
print(str(e))
|
logging.exception("Warning: Printer error or device not found!")
|
||||||
self.logger.info("Warning: Printer error or device not found!")
|
|
||||||
|
|
||||||
def _print_sale(self, sale, type_doc=None, open_box=False):
|
def _print_sale(self, sale, type_doc=None, open_box=False):
|
||||||
short = sale['short_invoice']
|
short = sale['short_invoice']
|
||||||
|
@ -432,7 +400,7 @@ class Receipt(object):
|
||||||
self._printer.set(align='center')
|
self._printer.set(align='center')
|
||||||
self._printer.image(self._img_logo, center=True)
|
self._printer.image(self._img_logo, center=True)
|
||||||
self.print_enter()
|
self.print_enter()
|
||||||
except:
|
except Exception:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
def print_qrcode(self, qrcode):
|
def print_qrcode(self, qrcode):
|
||||||
|
@ -440,11 +408,15 @@ class Receipt(object):
|
||||||
self.print_enter()
|
self.print_enter()
|
||||||
|
|
||||||
def print_tasks(self, data):
|
def print_tasks(self, data):
|
||||||
for value in data.values():
|
tasks_printed = []
|
||||||
|
for value in data:
|
||||||
try:
|
try:
|
||||||
self._printer = None
|
self._printer = None
|
||||||
self.config_printer(value['printer'])
|
self.config_printer(value['printer'])
|
||||||
self.set_printer()
|
self.set_printer()
|
||||||
|
if not self._printer:
|
||||||
|
logging.error('impresora no disponible error impresion tarea %s', str(value['printer']))
|
||||||
|
continue
|
||||||
title = value['sale'] + ' - ' + value['work_station']
|
title = value['sale'] + ' - ' + value['work_station']
|
||||||
self._printer.set(custom_size=True, width=2,
|
self._printer.set(custom_size=True, width=2,
|
||||||
height=2, align='center')
|
height=2, align='center')
|
||||||
|
@ -453,17 +425,18 @@ class Receipt(object):
|
||||||
height=2, align='left')
|
height=2, align='left')
|
||||||
self._printer.ln(2)
|
self._printer.ln(2)
|
||||||
for ln in value['lines']:
|
for ln in value['lines']:
|
||||||
line_ = str(int(ln['qty'])) + ' ' + ln['name']
|
line_ = str(int(ln['quantity'])) + ' ' + ln['name']
|
||||||
self._printer.textln(line_)
|
self._printer.textln(line_)
|
||||||
if ln.get('note'):
|
if ln.get('note'):
|
||||||
self._printer.textln('NOTA:' + ln.get('note'))
|
self._printer.textln('NOTA:' + ln.get('note'))
|
||||||
self._printer.ln(2)
|
self._printer.ln(2)
|
||||||
|
tasks_printed.append(ln['task'])
|
||||||
self._printer.cut()
|
self._printer.cut()
|
||||||
self._printer.close()
|
self._printer.close()
|
||||||
except Exception as e:
|
except Exception:
|
||||||
print(e)
|
logging.exception('error tarea')
|
||||||
traceback.print_exc()
|
|
||||||
time.sleep(1)
|
time.sleep(1)
|
||||||
|
return tasks_printed
|
||||||
|
|
||||||
def print_header(self, short=False):
|
def print_header(self, short=False):
|
||||||
if not short:
|
if not short:
|
||||||
|
@ -508,9 +481,9 @@ class Receipt(object):
|
||||||
def print_split(self, left, right):
|
def print_split(self, left, right):
|
||||||
len_left = self._row_characters - len(right) - 1
|
len_left = self._row_characters - len(right) - 1
|
||||||
left = left[:len_left]
|
left = left[:len_left]
|
||||||
if type(left) == bytes:
|
if isinstance(left, bytes):
|
||||||
left = left.decode("utf-8")
|
left = left.decode("utf-8")
|
||||||
if type(right) == bytes:
|
if isinstance(right, bytes):
|
||||||
right = right.decode("utf-8")
|
right = right.decode("utf-8")
|
||||||
left += (len_left - len(left) + 1) * ' '
|
left += (len_left - len(left) + 1) * ' '
|
||||||
self._printer.text(left)
|
self._printer.text(left)
|
||||||
|
@ -534,11 +507,11 @@ class Receipt(object):
|
||||||
if self._show_discount and discount and Decimal(discount) > 0:
|
if self._show_discount and discount and Decimal(discount) > 0:
|
||||||
amount_w_tax = Decimal(line['amount_w_tax'])
|
amount_w_tax = Decimal(line['amount_w_tax'])
|
||||||
discount = Decimal(discount)
|
discount = Decimal(discount)
|
||||||
initial = 'DCTO - ' + str(round(discount*100, 0)) + '%'
|
initial = 'DCTO - ' + str(round(discount * 100, 0)) + '%'
|
||||||
if discount == 1:
|
if discount == 1:
|
||||||
line_total = 0
|
line_total = 0
|
||||||
else:
|
else:
|
||||||
line_total = amount_w_tax/(1-discount)
|
line_total = amount_w_tax / (1 - discount)
|
||||||
discount = '-' + money(line_total - amount_w_tax)
|
discount = '-' + money(line_total - amount_w_tax)
|
||||||
line_total = money(line_total)
|
line_total = money(line_total)
|
||||||
|
|
||||||
|
@ -547,7 +520,7 @@ class Receipt(object):
|
||||||
length_name = self._row_characters - 11
|
length_name = self._row_characters - 11
|
||||||
first_line = code + ' ' + line['name'][:length_name]
|
first_line = code + ' ' + line['name'][:length_name]
|
||||||
|
|
||||||
if type(first_line) == bytes:
|
if isinstance(first_line, bytes):
|
||||||
first_line = first_line.decode('utf-8')
|
first_line = first_line.decode('utf-8')
|
||||||
|
|
||||||
self._printer.text(first_line + '\n')
|
self._printer.text(first_line + '\n')
|
||||||
|
@ -866,38 +839,40 @@ class Receipt(object):
|
||||||
if not hasattr(self, '_printer') or not self._printer and self._environment != 'restaurant':
|
if not hasattr(self, '_printer') or not self._printer and self._environment != 'restaurant':
|
||||||
self.set_printer()
|
self.set_printer()
|
||||||
if not self._printer:
|
if not self._printer:
|
||||||
self.logger.info(
|
logging.info(
|
||||||
"Warning: Interface not found for printer!")
|
"Warning: Interface not found for printer!")
|
||||||
# res.append(None)
|
# res.append(None)
|
||||||
return False
|
return False
|
||||||
|
|
||||||
self.logger.info("Info: Printer is OK!")
|
logging.info("Info: Printer is OK!")
|
||||||
try:
|
try:
|
||||||
self._print_order(order, reversion)
|
res = self._print_order(order, reversion)
|
||||||
# if True:
|
# if True:
|
||||||
res.extend(order['lines_ids'])
|
if res:
|
||||||
except Exception as e:
|
res.extend(res)
|
||||||
print(e)
|
elif order.get('lines_ids') and True:
|
||||||
traceback.print_exc()
|
res.extend(order['lines_ids'])
|
||||||
|
except Exception:
|
||||||
|
logging.exception('error de impresora')
|
||||||
self._printer.close()
|
self._printer.close()
|
||||||
time.sleep(1)
|
time.sleep(1)
|
||||||
except Exception as e:
|
except Exception:
|
||||||
print(e)
|
logging.exception('Can not found Printer!')
|
||||||
traceback.print_exc()
|
|
||||||
self.logger.info("Warning: Can not found Printer!")
|
|
||||||
return res
|
return res
|
||||||
|
|
||||||
def _print_order(self, order, reversion):
|
def _print_order(self, order, reversion):
|
||||||
|
lines_printed = []
|
||||||
for copie in range(self.order_copies):
|
for copie in range(self.order_copies):
|
||||||
self.print_body_order(order, reversion)
|
lines_printed = self.print_body_order(order, reversion)
|
||||||
self._print_info_consumer(order)
|
self._print_info_consumer(order)
|
||||||
self._printer.cut()
|
self._printer.cut()
|
||||||
return True
|
return lines_printed
|
||||||
|
|
||||||
def print_body_order(self, order, reversion):
|
def print_body_order(self, order, reversion):
|
||||||
# Exists 2 types of order:
|
# Exists 2 types of order:
|
||||||
# command => For restaurants kitchens
|
# command => For restaurants kitchens
|
||||||
# dispatch => For external dispatch
|
# dispatch => For external dispatch
|
||||||
|
lines_printed = []
|
||||||
self._printer.set(font=_FONT_B)
|
self._printer.set(font=_FONT_B)
|
||||||
self._printer.set(align='center')
|
self._printer.set(align='center')
|
||||||
turn = order.get('turn')
|
turn = order.get('turn')
|
||||||
|
@ -994,21 +969,25 @@ class Receipt(object):
|
||||||
|
|
||||||
def print_lines_order(lines, group=False):
|
def print_lines_order(lines, group=False):
|
||||||
for line in lines:
|
for line in lines:
|
||||||
if self.order_kind == 'command':
|
try:
|
||||||
self._printer.set(custom_size=True, width=1, height=2)
|
if self.order_kind == 'command':
|
||||||
qty = ' ' + str(int(Decimal(line['quantity'])))
|
self._printer.set(custom_size=True, width=1, height=2)
|
||||||
name = line['name']
|
qty = ' ' + str(int(Decimal(line['quantity'])))
|
||||||
if group:
|
name = line['name']
|
||||||
name = ' ' + name
|
if group:
|
||||||
self.print_col(qty, self.order_col_1)
|
name = ' ' + name
|
||||||
self.print_col(name, col_width_name)
|
self.print_col(qty, self.order_col_1)
|
||||||
if line['note']:
|
self.print_col(name, col_width_name)
|
||||||
self.print_enter()
|
if line['note']:
|
||||||
for msg_note in line['note'].split('\n'):
|
|
||||||
self._printer.text(f' NOTA -> {msg_note}')
|
|
||||||
self.print_enter()
|
self.print_enter()
|
||||||
|
for msg_note in line['note'].split('\n'):
|
||||||
|
self._printer.text(f' NOTA -> {msg_note}')
|
||||||
|
self.print_enter()
|
||||||
|
if line.get('id'):
|
||||||
|
lines_printed.append(line['id'])
|
||||||
|
except Exception:
|
||||||
|
traceback.print_exc()
|
||||||
self.print_enter()
|
self.print_enter()
|
||||||
print('este es el camino de la comanda')
|
|
||||||
self.print_enter()
|
self.print_enter()
|
||||||
if isinstance(order['lines'], list):
|
if isinstance(order['lines'], list):
|
||||||
print_lines_order(order['lines'])
|
print_lines_order(order['lines'])
|
||||||
|
@ -1031,6 +1010,7 @@ class Receipt(object):
|
||||||
self._printer.text(str(order['comment']))
|
self._printer.text(str(order['comment']))
|
||||||
self.print_enter()
|
self.print_enter()
|
||||||
self._printer.ln(2)
|
self._printer.ln(2)
|
||||||
|
return lines_printed
|
||||||
# if self._environment != 'retail':
|
# if self._environment != 'retail':
|
||||||
# self._printer.set(custom_size=True, width=2, height=2, align='center')
|
# self._printer.set(custom_size=True, width=2, height=2, align='center')
|
||||||
# title = f'+ + + {_kind} + + +'
|
# title = f'+ + + {_kind} + + +'
|
||||||
|
|
14
app/tools.py
14
app/tools.py
|
@ -27,3 +27,17 @@ def get_screen():
|
||||||
width = screen.width()
|
width = screen.width()
|
||||||
height = screen.height()
|
height = screen.height()
|
||||||
return width, height
|
return width, height
|
||||||
|
|
||||||
|
def compare_versions(version_validate, version_required):
|
||||||
|
v1_parts = version_validate.split('.')
|
||||||
|
v2_parts = version_required.split('.')
|
||||||
|
|
||||||
|
for i in range(max(len(v1_parts), len(v2_parts))):
|
||||||
|
v1_num = int(v1_parts[i]) if i < len(v1_parts) else 0
|
||||||
|
v2_num = int(v2_parts[i]) if i < len(v2_parts) else 0
|
||||||
|
|
||||||
|
if v1_num < v2_num:
|
||||||
|
return "lower"
|
||||||
|
elif v1_num > v2_num:
|
||||||
|
return "higher"
|
||||||
|
return 'equal'
|
||||||
|
|
|
@ -1 +1 @@
|
||||||
__version__ = "6.0.24"
|
__version__ = "6.0.25"
|
||||||
|
|
|
@ -0,0 +1,20 @@
|
||||||
|
import os
|
||||||
|
import logging
|
||||||
|
|
||||||
|
|
||||||
|
log_file_path = os.path.dirname(os.path.abspath(__file__)) + '/presik_pos.log'
|
||||||
|
log_formater = logging.Formatter(
|
||||||
|
'%(asctime)s - %(levelname)s - %(funcName)s - %(name)s - %(message)s',
|
||||||
|
datefmt='%Y-%m-%d %H:%M:%S', style="%")
|
||||||
|
|
||||||
|
|
||||||
|
handlerConsole = logging.StreamHandler()
|
||||||
|
handlerConsole.setFormatter(log_formater)
|
||||||
|
|
||||||
|
handlerFile = logging.FileHandler(log_file_path, mode='a', encoding='utf-8')
|
||||||
|
handlerFile.setFormatter(log_formater)
|
||||||
|
|
||||||
|
logger = logging.getLogger()
|
||||||
|
logger.setLevel(logging.DEBUG)
|
||||||
|
logger.addHandler(handlerConsole)
|
||||||
|
logger.addHandler(handlerFile)
|
Loading…
Reference in New Issue