diff --git a/app/commons/dblogin.py b/app/commons/dblogin.py index 3b66ee7..d52b74c 100644 --- a/app/commons/dblogin.py +++ b/app/commons/dblogin.py @@ -43,17 +43,6 @@ class Login(QDialog): params = Params(file_config) self.params = params.params self.setObjectName('dialog_login') - # if self.params.get('tablet_mode') == 'True': - # self.tablet_mode = eval(self.params['tablet_mode']) - # self.set_style([file_tablet_css]) - # else: - # if self.params.get('theme'): - # file_theme_css = os.path.join( - # pkg_dir, 'css', self.params['theme'] + '.css') - # self.set_style([file_theme_css]) - # else: - # self.set_style([file_base_css]) - # self.tablet_mode = None self.ui = Ui_Login() self.ui.setupUi(self) self.verify_conn_th = VerifyConn(self) @@ -94,82 +83,6 @@ class Login(QDialog): self.accept() event.accept() - # def init_UI(self): - # hbox_logo = QHBoxLayout() - # label_logo = QLabel() - # label_logo.setObjectName('label_logo') - # hbox_logo.addWidget(label_logo, 0) - # pixmap_logo = QPixmap(path_logo) - # label_logo.setPixmap(pixmap_logo) - # hbox_logo.setAlignment(label_logo, Qt.AlignHCenter) - - # values = OrderedDict([ - # ('host', {'name': 'SERVIDOR', 'readonly': True}), - # ('database', {'name': 'BASE DE DATOS', 'readonly': True}), - # ('user', {'name': 'USUARIO'}), - # ('password', {'name': 'CONTRASEƑA'}), - # ]) - # formLayout = GridForm(self, values=values, col=1) - # self.field_password.setEchoMode(QLineEdit.Password) - # self.field_password.textChanged.connect(self.clear_message) - - # box_buttons = QDialogButtonBox() - # if self.params.get('option_offline') == 'True': - # pushButtonOffline = QPushButton("ONLINE") - # pushButtonOffline.setObjectName('button_offline') - # pushButtonOffline.setIcon( - # self.style().standardIcon(getattr(QStyle, 'SP_DriveNetIcon'))) - # box_buttons.addButton( - # pushButtonOffline, QDialogButtonBox.ActionRole) - # pushButtonCancel = QPushButton("C&ANCELAR") - # pushButtonCancel.setObjectName('button_cancel') - # box_buttons.addButton(pushButtonCancel, QDialogButtonBox.RejectRole) - # pushButtonOk = QPushButton("&CONNECTAR") - # pushButtonOk.setAutoDefault(True) - # pushButtonOk.setDefault(False) - # pushButtonOk.setObjectName('button_ok') - # box_buttons.addButton(pushButtonOk, QDialogButtonBox.AcceptRole) - - # hbox_buttons = QHBoxLayout() - # hbox_buttons.addWidget(box_buttons) - - # line = QFrame() - # line.setFrameShape(line.HLine) - # line.setFrameShadow(line.Sunken) - # hbox_line = QHBoxLayout() - # hbox_line.addWidget(line) - - # hbox_msg = QHBoxLayout() - # self.error_msg = QLabel('Error: usuario o contraseƱa invalida...!') - # self.error_msg.setObjectName('login_msg_error') - # self.error_msg.setAlignment(Qt.AlignCenter) - # hbox_msg.addWidget(self.error_msg) - - # hbox_version = QHBoxLayout() - # label_version = QLabel('VERSION: ' + __version__) - # label_version.setMargin(20) - # font_version = QFont('Times') - # label_version.setFont(font_version) - # hbox_version.addWidget(label_version) - # hbox_version.setAlignment(Qt.AlignCenter) - - # vbox_layout = QVBoxLayout() - # vbox_layout.addLayout(hbox_logo) - # vbox_layout.addLayout(formLayout) - # vbox_layout.addLayout(hbox_msg) - # vbox_layout.addLayout(hbox_line) - # vbox_layout.addLayout(hbox_buttons) - # vbox_layout.addLayout(hbox_version) - - # self.setLayout(vbox_layout) - # self.setWindowTitle('Login Presik System') - # self.clear_message() - - # self.field_password.setFocus() - # box_buttons.accepted.connect(self.accept) - # box_buttons.rejected.connect(self.reject) - # box_buttons.clicked.connect(self.clicked) - def clear_message(self): self.error_msg.hide() @@ -240,16 +153,10 @@ def xconnection(mode, user, password, host, database, port): conn = HTTPConnection(host, port=port, timeout=10) else: conn = HTTPSConnection(host, port=port, timeout=10, context=context_http) - url = '/' + database + '/login' + url = '/' + database + '/fast_login' payload = { - 'method': "common.db.login", - 'params': [ - user, - {'device_cookie': None, 'password': password}, - "es", - ], - 'id': 0, - 'context': {}, + 'username': user, + 'passwd': password } try: conn.request('POST', url, body=json.dumps(payload), headers=HEADERS) @@ -258,9 +165,6 @@ def xconnection(mode, user, password, host, database, port): status = 408 response = None print(e, 'error') - - # url = '%s://%s:%s@%s:%s/%s/' % ( - # mode, user, password, host, 8000, database) try: res = json.loads(response.read()) if not res.get('status'): @@ -279,38 +183,3 @@ def xconnection(mode, user, password, host, database, port): conn.close() return res - # return connection.set_xmlrpc(url) - - -# def safe_reconnect(main): -# field_password = QLineEdit() -# field_password.setEchoMode(QLineEdit.Password) -# field_password.cursorPosition() -# field_password.cursor() -# dialog_password = QuickDialog(main, 'question', -# info=main.tr('Enter your password:'), -# widgets=[field_password], -# buttons=['ok'], -# response=True -# ) -# field_password.setFocus() - -# password = field_password.text() -# if not password or password == '': -# safe_reconnect(main) - -# main.conn = xconnection( -# main.user, -# str(password), -# main.server, -# main.port, -# main.database, -# main.protocol, -# ) - -# if main.conn: -# field_password.setText('') -# dialog_password.hide() -# main.global_timer = 0 -# else: -# safe_reconnect(main) diff --git a/app/frontwindow.py b/app/frontwindow.py index a9c3d95..31afbd5 100644 --- a/app/frontwindow.py +++ b/app/frontwindow.py @@ -10,7 +10,7 @@ from PySide6.QtCore import QTimer, QThread, Signal from PySide6.QtGui import QGuiApplication from .commons.dialogs import QuickDialog # from .commons.dblogin import safe_reconnect -from .proxy import Model +from .proxy import Model, logout from .constants import SCREENS from .dialogs import ( Help, ControlPanel, SearchSale, SearchParty, SearchProduct, Position, @@ -108,32 +108,18 @@ class FrontWindow(QMainWindow): styles.append(infile.read()) self.setStyleSheet(''.join(styles)) - # def set_timeout(self): - # if self.active_timeout != 'True': - # return - - # self.timeout = eval(self.timeout) - # if not self.timeout: - # self.timeout = _DEFAULT_TIMEOUT - # timer = QTimer(self) - # timer.timeout.connect(self.count_time) - # timer.start(1000) - - # def count_time(self): - # self.global_timer += 1 - # if self.global_timer > self.timeout: - # self.global_timer = 0 - # print('error esta linea no debia ejecutarse') - # # safe_reconnect() - - def close(self): + def closeEvent(self, event): dialog = self.dialog('confirm_exit', response=True) response = dialog.exec_() if response == DIALOG_REPLY_YES: self.check_empty_sale() + logout(self.ctx) if self.active_weighing and self.reader_thread: self.reader_thread.onClose() super(FrontWindow, self).close() + else: + event.ignore() + def dialog(self, name, response=False, widgets=None, extra_message=None): kind, msg = self.stack_msg[name] @@ -150,15 +136,6 @@ class FrontWindow(QMainWindow): v = eval(v) setattr(self, k, v) - # def action_block(self): - # safe_reconnect(self) - - # def dialog_password_accept(self): - # self.connection() - - # def dialog_password_rejected(self): - # self.connection() - def keyReleaseEvent(self, event): self._keyStates[event.key()] = False @@ -242,10 +219,6 @@ class FrontWindow(QMainWindow): self.sale_automatic = True res = self.Sale.fields_get(['commission']) self._commission_activated = True if res.get('commission') else False - # self._source = self.Module.find([ - # ('name', '=', 'sale_source'), - # ('state', '=', 'activated'), - # ]) self._credit_limit_activated = self.Module.find([ ('name', '=', 'account_credit_limit'), ('state', '=', 'activated'), diff --git a/app/main.py b/app/main.py index 73e533c..bd12710 100644 --- a/app/main.py +++ b/app/main.py @@ -177,7 +177,7 @@ class AppWindow(FrontWindow): self.active_usb_printers.append(['usb', path_device]) def get_current_sale(self): - if hasattr(self, '_sale') and self._sale['id']: + if hasattr(self, '_sale') and self._sale.get('id'): sales = self.Sale.find([ ('id', '=', self._sale['id']) ]) @@ -2784,12 +2784,14 @@ class AppWindow(FrontWindow): self._sale_line = res self._current_line_id = res['id'] self.add_sale_line(res) - if record: - self._sale_line['product'] = record self.product_id = product_id self.message_bar.set('system_ready') self.set_amounts() self.set_state('add') + if record: + self._sale_line['product'] = record + if len(record.get('products_mix')) > 0: + self.action_combo(record['code']) def _check_stock_quantity(self, product, request_qty=None): if not isinstance(product['quantity'], (str, int, float, Decimal)): @@ -3100,12 +3102,13 @@ class AppWindow(FrontWindow): self.validate_discount(rec, _line) self.dialog_product_edit.close() - def action_combo(self): - line = self.dialog_product_edit.get() - try: - code = line['product.']['code'] - except: - code = line['product']['code'] + def action_combo(self, code=None): + if not code: + line = self.dialog_product_edit.get() + try: + code = line['product.']['code'] + except: + code = line['product']['code'] product = self.Product.find( [('code', '=', code)], fields=["code", "description", "extra_tax", "name", "sale_uom", diff --git a/app/models.py b/app/models.py index 039ea62..0acc107 100644 --- a/app/models.py +++ b/app/models.py @@ -111,9 +111,11 @@ MODELS_RESTAURANT = { 'shop.product_categories.products.id', 'shop.product_categories.products.name', 'shop.product_categories.products.code', + 'shop.product_categories.products.products_mix', 'shop.product_categories.childs.products.id', 'shop.product_categories.childs.products.name', 'shop.product_categories.childs.products.code', + 'shop.product_categories.childs.products.products_mix', 'journal.name', 'journal.kind', 'journal.require_voucher', diff --git a/app/proxy.py b/app/proxy.py index 38354ba..7f7518d 100644 --- a/app/proxy.py +++ b/app/proxy.py @@ -6,8 +6,6 @@ from datetime import date from decimal import Decimal from http.client import HTTPConnection, HTTPSConnection import orjson as json -# import simplejson as json -# import requests try: from app.models import MODELS_RESTAURANT, MODELS_RETAIL except: @@ -39,6 +37,30 @@ def encoder(obj): return str(obj) raise TypeError(repr(obj) + " is not JSON serializable") +def logout(ctx): + port = ctx['params']['port'] + host = ctx['params']['server'] + db = ctx['params']['database'] + if ctx['params']['mode'] == 'http': + conn = HTTPConnection(host, port=port) + else: + conn = HTTPSConnection(host, port=port, context=context_http) + url = '/' + db + '/logout' + payload = json.dumps( + { + 'session':ctx['session'], + 'login': ctx['login'] + }, + default=encoder) + conn.request('POST', url, body=payload, headers=HEADERS) + response = conn.getresponse() + if response.status != 200: + res = response.read() + else: + res = json.loads(response.read()) + conn.close() + return res + class Model(object): @@ -48,6 +70,7 @@ class Model(object): self.port = ctx['params']['port'] self.host = ctx['params']['server'] self.db = ctx['params']['database'] + HEADERS['Authorization'] = "Bearer " + ctx['session'] # self.api = 'http://localhost:8010/ZIRUS' if ctx['params']['mode'] == 'http': self.conn = HTTPConnection @@ -98,10 +121,6 @@ class Model(object): } res = self.get_connection('POST', '/fields_get', args_) return res - # route = self.get_route('search') - # data = json.dumps(args_, default=encoder) - # res = requests.post(route, data=data) - # return res.json() def write_many(self, ids, values, fields=None): if not fields: @@ -115,10 +134,6 @@ class Model(object): } res = self.get_connection('POST', '/save_many', args_) return res - # route = self.get_route('save_many') - # data = json.dumps(args_, default=encoder) - # res = requests.put(route, data=data) - # return res.json() def write(self, ids, values, fields=None): if not fields: @@ -134,10 +149,6 @@ class Model(object): } res = self.get_connection('POST', '/write', args_) return res - # route = self.get_route('write') - # data = json.dumps(args_, default=encoder) - # res = requests.post(route, data=data) - # return res.json() def create(self, values): if values.get('rec_name'): @@ -159,10 +170,6 @@ class Model(object): } res = self.get_connection('POST', '/method_instance', args_) return res - # route = self.get_route('create') - # data = json.dumps(args_, default=encoder) - # res = requests.post(route, data=data) - # return res.json() def delete(self, ids): args_ = { @@ -172,14 +179,6 @@ class Model(object): } res = self.get_connection('POST', '/delete', args_) return res - # route = self.get_route('delete') - # data = json.dumps(args_, default=encoder) - # res = requests.post(route, data=data) - # return res.json() - - # def get_route(self, target): - # route = self.api + '/' + target - # return route def get_connection(self, method, target, data=None): url = '/' + self.db + target @@ -223,15 +222,6 @@ class Model(object): } res = self.get_connection('POST', '/button_method', args_) return res - # route = self.get_route('method') - # data = json.dumps(args_, default=encoder) - # res = requests.post(route, data=data) - # response = None - # try: - # response = res.json() - # except ValueError: - # pass - # return response class Report(object): @@ -261,10 +251,6 @@ class Report(object): conn.close() return res - # def get_route(self, target): - # route = self.api + '/' + target - # return route - def get(self, values): args_ = { 'report': values['report_name'], @@ -275,16 +261,9 @@ class Report(object): } res = self.get_connection('POST', '/report', args_) return res - # route = self.get_route('report') - # data = json.dumps(args_, default=encoder) - # res = requests.post(route, data=data) def open(self, args): oext, content, direct_print, file_name = args - # oext = args['oext'] - # content = args['content'] - # direct_print = args['direct_print'] - # name = args['name'] dtemp = tempfile.mkdtemp(prefix='tryton_') fp_name = os.path.join( diff --git a/app/reporting.py b/app/reporting.py index 59c6420..5c8721d 100755 --- a/app/reporting.py +++ b/app/reporting.py @@ -423,17 +423,17 @@ class Receipt(object): self._printer = None self.config_printer(value['printer']) self.set_printer() - sale = value['sale']['number'] + title = value['sale'] + ' - ' + value['work_station'] self._printer.set(custom_size=True, width=2, height=2, align='center') - self._printer.textln(sale) + self._printer.textln(title) self._printer.set(custom_size=False) self._printer.ln(2) for ln in value['lines']: line_ = str(int(ln['qty'])) + ' ' + ln['name'] self._printer.textln(line_) - desc = ln['description'] - self._printer.textln(desc) + if ln.get('description'): + self._printer.textln(ln.get('description')) if ln.get('note'): self._printer.textln('NOTA:' + ln.get('note')) self._printer.ln(2)