new release version add option debug

This commit is contained in:
Wilson Gomez 2023-10-20 16:43:40 -05:00
parent c9b2f22b29
commit 543385d0fa
12 changed files with 281 additions and 238 deletions

1
.gitignore vendored
View File

@ -21,6 +21,7 @@
npm-debug.log*
yarn-debug.log*
yarn-error.log*
*.log*
package-lock*

View File

@ -63,12 +63,15 @@ class StartButtons(QVBoxLayout):
values_extend([
['button_control_panel', 'PANEL DE CONTROL', 'action_control_panel', 'settings'],
['button_reports', 'REPORTES', 'action_reports', 'reports'],
['button_historic_sales', 'HISTORIAL', 'action_historic_sales', 'sales_history'],
])
if parent.environment == 'retail':
values_extend([
['button_collection', 'RECAUDO', 'action_collection', 'collection']
])
else:
values_extend([
['button_historic_sales', 'HISTORIAL', 'action_historic_sales', 'sales_history'],
])
values_extend([
['button_help', 'AYUDA', 'action_help', 'help'],
@ -156,7 +159,7 @@ class ButtonsFunction(QGridLayout):
['button_change_salesman', 'CAMBIO VENDEDOR', 'action_change_salesman'],
])
pos_user = self.parent.type_pos_user
if pos_user in ('order' ,'salesman'):
if pos_user in ('order', 'salesman'):
self.values.extend([
['button_to_draft', 'BORRADOR', 'button_to_draft_pressed'],
['button_to_quote', 'COTIZAR', 'button_to_quote_pressed'],

View File

@ -6,9 +6,8 @@ import gettext
import logging
import time
import ssl
from collections import OrderedDict
from pathlib import Path
from PySide6.QtWidgets import (QMainWindow, QDialog)
from PySide6.QtWidgets import QDialog
from PySide6.QtCore import Qt, QTimer
from PySide6.QtGui import QPixmap
from http.client import HTTPConnection, HTTPSConnection
@ -16,6 +15,7 @@ import orjson as json
from app.threads import VerifyConn
from app.commons.config import Params
from app.commons.ui_login import Ui_Login
from logger_config import logger
context_http = ssl._create_unverified_context()
_ = gettext.gettext
@ -57,8 +57,7 @@ class Login(QDialog):
conn.close()
option = u"online"
icon_conn = path_circle_green
except Exception as e:
print(e, 'error')
except Exception:
icon_conn = path_circle_red
option = u"offline"
self.ui.label_conn.setText(option)
@ -135,7 +134,8 @@ class Login(QDialog):
msg = 'Error: conexion del servidor'
elif result['status'] == 500:
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.error_message()
else:

View File

@ -7,7 +7,6 @@ from collections import OrderedDict
# )
# from PyQt5.QtGui import QStandardItem, QStandardItemModel, QPixmap
# from PyQt5.QtCore import Qt, pyqtSlot, QModelIndex
from operator import methodcaller
from PySide6.QtWidgets import (
QDialog, QAbstractItemView, QVBoxLayout, QHBoxLayout, QLabel, QWidget,
QTreeView, QLineEdit, QTableView, QCompleter
@ -179,7 +178,7 @@ class QuickDialog(QDialog):
print('cancell quitdialog')
try:
self.parent.label_input.setFocus()
except:
except Exception:
pass
self.setResult(0)
self.hide()

View File

@ -1,16 +1,16 @@
from decimal import Decimal
from datetime import datetime
from operator import itemgetter, attrgetter
from operator import itemgetter
from .commons.dialogs import HelpDialog, QuickDialog
# from PyQt5.QtCore import Qt, QSize
# from PyQt5.QtWidgets import (
# QCheckBox, QTextEdit, QVBoxLayout, QGridLayout, QLineEdit, QPlainTextEdit,
# QScrollArea, QHBoxLayout, QDoubleSpinBox, QLabel, QMessageBox
# )
from PySide6.QtCore import Qt, QSize
from PySide6.QtCore import Qt
from PySide6.QtWidgets import (
QCheckBox, QTextEdit, QVBoxLayout, QGridLayout, QLineEdit, QPlainTextEdit,
QScrollArea, QHBoxLayout, QDoubleSpinBox, QLabel, QMessageBox, QWidget
QScrollArea, QHBoxLayout, QDoubleSpinBox, QLabel, QWidget
)
from .proxy import Report
@ -287,8 +287,8 @@ class SearchParty(SearchWindow):
# 'street': parent.on_selected_street_party
}
super(SearchParty, self).__init__(parent, headers, None, methods,
filter_column=[], cols_width=[60, 120, 270, 190, 90],
title=title, fill=True)
filter_column=[], cols_width=[60, 120, 270, 190, 90],
title=title, fill=True)
class SearchProduct(SearchWindow):
@ -350,7 +350,7 @@ class SearchProduct(SearchWindow):
fields_names = list(headers.keys())
try:
fields_names.remove('image')
except:
except Exception:
pass
self.fields_names = fields_names
super(SearchProduct, self).__init__(parent, headers, None, methods,
@ -594,7 +594,7 @@ class DialogSaleForm(QuickDialog):
elements = (
'id', 'party.', 'number', 'sale_date',
'total_amount_cache', 'invoice_number', 'lines.'
)
)
id, party, number, sale_date, total_amount_cache, invoice_number, lines = itemgetter(*elements)(data)
self.sale_customer_selected = id
self.field_party.setText(party['name'])
@ -887,7 +887,7 @@ class DialogTableDeliveryParty(QuickDialog):
method_selected_row=parent.delivery_party_selected
)
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()
grid = QGridLayout()
@ -923,7 +923,7 @@ class DialogMoneyCount(QuickDialog):
grid = QGridLayout()
_sizes = (160, 120, 240)
fields = (
{'label': 'MONEDA', 'type': 'integer', 'readonly': True},
{'label': 'MONEDA', 'type': 'integer', 'readonly': True},
{'label': 'CANTIDAD', 'type': 'integer', 'change': 'set_total'},
{'label': 'SUBTOTAL', 'type': 'integer', 'readonly': True},
)
@ -1029,8 +1029,8 @@ class DialogExpenses(QuickDialog):
_sizes = (140, 290, 210, 150)
fields = (
{'name': 'id', 'label': 'ID', 'type': 'integer', 'invisible': True},
{'name': 'invoice_number', 'label': 'FACTURA', 'type': 'char'},
{'name': 'id', 'label': 'ID', 'type': 'integer', 'invisible': True},
{'name': 'invoice_number', 'label': 'FACTURA', 'type': 'char'},
{'name': 'description', 'label': 'DESCRIPCION', 'type': 'char'},
{'name': 'reference', 'label': 'REFERENCIA', 'type': 'char'},
{'name': 'amount', 'label': 'VALOR', 'type': 'float', 'change': 'set_total'},
@ -1126,7 +1126,7 @@ class DialogTaxes(QuickDialog):
'heads': ['ID', 'VALOR'],
}
string = 'ESCOJA EL IMPUESTO'
super(DialogTaxes, self).__init__(parent, 'selection', string, data)
super(DialogTaxes, self).__init__(parent, 'selection', string, data)
class DialogSource(QuickDialog):
@ -1485,7 +1485,7 @@ class DialogComboProduct(QuickDialog):
self.label_qty_min = QLabel('CANT. MIN.')
self.label_qty_min.setObjectName('label_qty_min')
self.hbox.addWidget(self.label_qty_min)
self.label_qty_min_req = QLabel("")
self.label_qty_min_req.setObjectName('label_qty_min_req')
self.hbox.addWidget(self.label_qty_min_req)
@ -1609,7 +1609,8 @@ class Help(HelpDialog):
('DOMICILIARIO', 'F12'),
('POSICION', 'Insert'),
('FACTURAR', 'End'),
('COMENTARIO', 'Quotation Marks'),
('COMENTARIO', 'COMILLAS DOBLE (")'),
('AGENTE', 'PUNTO Y COMA (;)'),
)
self.set_shortcuts(shortcuts)
@ -1618,7 +1619,6 @@ class Help(HelpDialog):
class DialogListProduct(QuickDialog):
def __init__(self, parent):
self._parent = parent
vbox = QVBoxLayout()
grid = QGridLayout()
label_code = QLabel('CODIGO:')
label_code.setObjectName('label_info_product_code')
@ -1806,7 +1806,7 @@ class DialogCollection(QuickDialog):
self.input_filter.setObjectName('input_collection_filter')
self.input_filter.editingFinished.connect(lambda: self.search())
self.input_filter.returnPressed.connect(lambda: self.search())
grid.addWidget(self.input_filter, 1, 2)
label_id_number = QLabel('DOCUMENTO:')
@ -1836,8 +1836,8 @@ class DialogCollection(QuickDialog):
label_payment_method.setObjectName('label_collection_payment_method')
grid.addWidget(label_payment_method, 5, 1)
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)
label_voucher_number = QLabel('NUMERO COMPROBANTE:')
@ -1862,8 +1862,8 @@ class DialogCollection(QuickDialog):
def get_payment_methods(self):
domain = [
["sale_device", "=", self._parent.device['id']],
["state", "=", "draft"]
["sale_device", "=", self._parent.device['id']],
["state", "=", "draft"]
]
statements = self._parent.Statement.find(domain,
fields=['rec_name', 'journal.require_voucher'])

View File

@ -3,10 +3,7 @@ import time
from datetime import date
import logging
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.QtCore import QTimer, QThread, Signal
from PySide6.QtGui import QGuiApplication
from .commons.dialogs import QuickDialog
# from .commons.dblogin import safe_reconnect
@ -29,11 +26,12 @@ from .constants import DIALOG_REPLY_YES
from .version import __version__
__all__ = ['FrontWindow', 'ClearUi']
__all__ = ['FrontWindow']
parent = Path(__file__).parent
file_base_css = os.path.join(str(parent), 'css', 'base.css')
_DEFAULT_TIMEOUT = 60000 # on ms (100 minutes)
logger = logging.getLogger(__name__)
class FrontWindow(QMainWindow):
@ -50,7 +48,6 @@ class FrontWindow(QMainWindow):
# self.conn = connection
self.version = __version__
self.set_params(params)
self.logger = logging.getLogger('app_logger')
"""
We need get the size of screen (display)
@ -201,6 +198,14 @@ class FrontWindow(QMainWindow):
self._sale_pos_restaurant = None
time1 = time.time()
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')
self.Config = Model('sale.configuration', 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
res = self.Sale.fields_get(['commission'])
self._commission_activated = True if res.get('commission') else False
self._credit_limit_activated = self.Module.find([
('name', '=', 'account_credit_limit'),
('state', '=', 'activated'),
])
self._credit_limit_activated = 'account_credit_limit' in self.modules
# _product = {
# 'name': 'product.product',
@ -340,20 +342,13 @@ class FrontWindow(QMainWindow):
self._password_admin = self._config.get('password_admin_pos')
self._password_force_assign = self._config.get('password_force_assign')
if self.environment == 'restaurant':
self._sale_pos_restaurant = self.Module.find([
('name', '=', 'sale_pos_frontend_rest'),
('state', '=', 'activated'),
])
self._sale_pos_restaurant = 'sale_pos_frontend_rest' in self.modules
print(self._sale_pos_restaurant, 'validate rest')
if self._sale_pos_restaurant:
self.RestTables = Model('sale.shop.table', 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 = None, None
try:
self.printers_shop, self.products_printers = self.Sale.get_product_printers(
self.shop['id'])
except Exception:
pass
self.printers_shop, self.products_printers = self.Sale.get_product_printers(
self.shop['id'])
self._action_report_invoice, = self.ActionReport.find([
('report_name', '=', 'account.invoice'),
@ -374,17 +369,3 @@ class FrontWindow(QMainWindow):
self.Source = Model('sale.source', self.ctx, main_window=self)
self.Pricelist = Model('product.price_list', self.ctx, main_window=self)
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()

View File

@ -7,7 +7,7 @@ import base64
import time
import traceback
from decimal import Decimal
from datetime import datetime, timedelta, date
from datetime import datetime, timedelta
from collections import OrderedDict
from PySide6 import QtGui
from PySide6.QtCore import Qt, QTimer
@ -16,7 +16,7 @@ from PySide6.QtWidgets import (
QWidget)
from app.commons.image import Image
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 .stack_messages import StackMessages
# from app.commons.action import Action
@ -31,7 +31,7 @@ from .proxy import Report
from .buttonpad import ButtonsStacked, ButtonsFunction, StartButtons
from .states import STATES, RE_SIGN
from .commons.custom_button import CustomButton
from .threads import DoInvoice, VerifyOrderCommand
from .threads import DoInvoice
from .store import StoreView
from .constants import (
PATH_PRINTERS, DELTA_LOCALE, STRETCH, alignRight, alignLeft, alignCenter,
@ -76,7 +76,8 @@ class AppWindow(FrontWindow):
return
self.setup_sale_line()
self.setup_delivery_party()
self.setup_sale_consumer()
if self.environment == 'restaurant':
self.setup_sale_consumer()
self.setup_payment()
# self.set_domains()
print(time.time() - time1, 'set domains')
@ -106,19 +107,16 @@ class AppWindow(FrontWindow):
self.reader_thread = ScaleReader()
self.reader_thread.sigSetWeight.connect(self.set_weight_readed)
if self.server_printer:
self.verify_command_order_th = VerifyOrderCommand(self)
self.verify_command_order_th.sigVerifyOrderCommand.connect(self.verify_print_order_automatic)
self.verify_command_order_th.start()
if self.server_printer and self.environment == 'restaurant':
timer = QTimer()
timer.timeout.connect(self.verify_print_order_automatic)
timer.start(30000)
self.do_invoice = DoInvoice(self, self.ctx)
self.do_invoice.sigDoInvoice.connect(self.__do_invoice_thread)
self.set_state('disabled')
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)
if matching_journal:
self.default_journal = matching_journal
@ -136,24 +134,45 @@ class AppWindow(FrontWindow):
self.field_agent = None
def verify_print_order_automatic(self):
records = self.Sale.get_orders_to_command({'shop': self.shop['id']})
for record in records:
orders = record['orders']
tasks = record['tasks']
try:
result = self.receipt_order.print_orders(orders.values())
if result:
self.Sale.mark_commanded({'sale_id': record['id'], 'lines_ids': result})
receipt = Receipt(context={}, environment='restaurant')
receipt.print_tasks(tasks)
except Exception as e:
print(e)
traceback.print_exc()
args = {'shop': self.shop['id']}
orders = []
tasks = []
version = compare_versions(self.modules['sale_pos_frontend_rest']['version'], '6.0.7')
if version in ('equal', 'higher'):
print('pasa por esta new query')
if not self.tasks_station:
orders = self.SaleLine.get_data_command(args)
else:
result = self.SaleLine.get_data_command_and_task(args)
orders = result['orders']
tasks = result['tasks']
timer = QTimer()
timer.timeout.connect(self.verify_print_order_automatic)
timer.start(30000)
self.verify_command_order_th.exit(0)
# TODO: for remove this option
else:
records = self.Sale.get_orders_to_command(args)
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):
# self.domain_search_product = [
@ -1745,7 +1764,7 @@ class AppWindow(FrontWindow):
}
orders, sale_number = self.Sale.get_reversion(args)
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')
logging.error('Printing order reversion fail!')
@ -1823,10 +1842,11 @@ class AppWindow(FrontWindow):
if res == DIALOG_REPLY_NO:
return False
result = None
if not sale.get('number'):
result_set = self.Sale.set_sale_number({'sale_id': sale_id})
self.store.set({'number': result_set})
self.order_number.setText(result_set)
number = sale.get('number')
if not number:
number = self.Sale.set_sale_number({'sale_id': sale_id})
self.store.set({'number': number})
self.order_number.setText(number)
if self.environment == 'restaurant':
if self.print_order:
result = self.print_command(sale)
@ -1842,6 +1862,7 @@ class AppWindow(FrontWindow):
def get_header_sale(self, sale):
order = {
'id': self.sale_id,
'sale_number': sale['number'],
'number': sale.get('invoice_number'),
'turn': sale.get('turn'),
@ -1875,65 +1896,87 @@ class AppWindow(FrontWindow):
return result
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
lines = [line_reversion] if reversion else self.model_sale_lines._data
orders = {}
lines_ids = []
for ln in lines:
if not reversion and ln['order_sended'] in (True, ''):
continue
pd_id = ln['product.']['id']
try:
printers, cat_id = self.products_printers.get(str(pd_id))
cat_id = str(cat_id[0])
except Exception:
traceback.print_exc()
printers, cat_id = None, None
if printers:
for printer_id in printers:
printer = self.printers_shop.get(str(printer_id))
if printer_id not in orders.keys():
orders[printer_id] = {
**order,
**printer,
'lines_ids': []
lines = [line_reversion] if reversion else self.model_sale_lines._data
if version in ('equal', 'higher'):
order = self.get_header_sale(sale)
for ln in lines:
if not reversion and ln['order_sended'] in (True, ''):
continue
pd_id = ln['product.']['id']
try:
printers, cat_id = self.products_printers.get(str(pd_id))
cat_id = str(cat_id[0])
except Exception:
traceback.print_exc()
printers, cat_id = None, None
if printers:
for printer_id in printers:
printer = self.printers_shop.get(str(printer_id))
if printer_id not in orders.keys():
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'):
orders[printer_id]['lines'] = {**printer['lines']}
orders[printer_id]['categories'] = {**printer['categories']}
if isinstance(orders[printer_id]['lines'], list):
orders[printer_id]['lines'].append(value_line)
orders[printer_id]['lines_ids'].append(ln['id'])
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 isinstance(orders[printer_id]['lines'], list):
orders[printer_id]['lines'].append(value_line)
orders[printer_id]['lines_ids'].append(ln['id'])
else:
try:
key_id = orders[printer_id]['categories'][cat_id]
except Exception:
if 'others' not in orders[printer_id]['lines'].keys():
orders[printer_id]['lines']['others'] = {'name': 'OTROS', 'lines':[]}
key_id = 'others'
try:
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'])
try:
key_id = orders[printer_id]['categories'][cat_id]
except Exception:
if 'others' not in orders[printer_id]['lines'].keys():
orders[printer_id]['lines']['others'] = {'name': 'OTROS', 'lines': []}
key_id = 'others'
try:
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:
lines_ids.append(ln['id'])
else:
# for remove this code
if reversion:
args = {'sale_id': self.sale_id, 'sale_line_id': line_reversion['id']}
orders, sale_number = self.Sale.get_reversion(args)
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:
data_station = self.Sale.method_instance('get_data_for_stations', self.sale_id)
receipt = Receipt(context={}, environment='restaurant')
receipt.print_tasks(data_station)
if version in ('equal', 'higher'):
args = {
'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)
lines_sended = result + lines_ids
if not reversion and lines_sended:
@ -1960,11 +2003,12 @@ class AppWindow(FrontWindow):
if self._ask_new_sale():
self.create_new_sale()
def numpad_price_clicked(self):
code = self.label_input.text()
product = self._search_product(code)
if not product:
return
# for remove
# def numpad_price_clicked(self):
# code = self.label_input.text()
# product = self._search_product(code)
# if not product:
# return
def _ask_new_sale(self):
dialog = self.dialog('new_sale', response=True)
@ -2235,7 +2279,7 @@ class AppWindow(FrontWindow):
if sale.get('payments'):
for payment in sale['payments']:
# FIXME
#self.table_payment_lines.record_add(payment)
# self.table_payment_lines.record_add(payment)
pass
self.party_id = sale['party.']['id']
@ -2431,7 +2475,7 @@ class AppWindow(FrontWindow):
qty_text = self.dialog_combo_product.label_qty_add.text()
try:
qty = int(qty_text) + 1
except:
except Exception:
qty = 1
self.dialog_combo_product.label_qty_add.setText(str(qty))
self.on_selected_item(record, list_price)
@ -2557,7 +2601,7 @@ class AppWindow(FrontWindow):
ctx = 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:
ctx['price_list'] = self.shop['price_list.']['id']
fields = self.dialog_search_products.fields_names
@ -2795,14 +2839,14 @@ class AppWindow(FrontWindow):
('barcode', '=', code),
('code', '=', code)
])
# 'image', 'image_icon', 'write_date' fields remove from domain
products = self.Product.find(
domain,
fields=[
'name', 'code', 'categories', 'description',
'id', 'image', 'image_icon', 'list_price',
'quantity', 'rec_name', 'template',
'id', 'list_price', 'quantity', 'rec_name', 'template',
'extra_tax', 'template.sale_price_w_tax',
'template.default_uom', 'write_date'])
'template.default_uom'])
if not products or len(products) > 1:
self.message_bar.set('product_not_found')
@ -2856,6 +2900,7 @@ class AppWindow(FrontWindow):
product_id = record['id'] if record else None
if not product_id and code:
# REMOVE ME THIS OPTION IS FOR BARCODE
# product = self._search_product(code)
product = self._search_product(code)
if product:
product_id = product['id']
@ -3282,7 +3327,8 @@ class AppWindow(FrontWindow):
if note:
self.SaleLine.write([removed_item['id']], {'note': note})
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.SaleLine.delete([removed_item['id']])
self.set_amounts()

View File

@ -388,7 +388,6 @@ MODELS_RETAIL = {
'new_sale_automatic', 'show_product_image', 'delivery_product.code',
'encoded_sale_price', 'delivery_product.list_price',
'delivery_product.name', 'allow_discount_handle',
'no_remove_commanded',
'cache_products_local', 'show_party_categories',
'print_lines_product', 'uvt_pos'
]

View File

@ -8,7 +8,6 @@ from datetime import datetime
from decimal import Decimal
import subprocess
import time
from .printing.protocols import FileSSH
try:
@ -77,7 +76,6 @@ class Receipt(object):
__name__ = 'frontend_pos.ticket'
def __init__(self, context={}, row_characters=None, logo=None, environment='retail'):
self.logger = logging.getLogger('reporting')
self._company = context.get('company')
self._sale_device = context.get('sale_device')
self._shop = context.get('shop')
@ -217,18 +215,16 @@ class Receipt(object):
except Exception:
host, port = self._device, None
if port:
self._printer = printer.Network(host, port=int(port), timeout=15)
self._printer = printer.Network(host, port=int(port), timeout=5)
else:
self._printer = printer.Network(host, timeout=15)
self._printer = printer.Network(host, timeout=5)
if not self._printer:
msg = "Warning: Can not found Printer!"
self.logger.info("Warning: Can not found Printer!")
logging.info("Warning: Can not found Printer!")
return msg
self.logger.info("Info: Printer is OK!")
except Exception as e:
traceback.print_exc()
self.logger.info(
"Warning: Printer error or device not found!", str(e))
except Exception:
logging.exception(
"Warning: Printer error or device not found!")
def print_sale(self, sale, type_doc=None, open_box=False):
try:
@ -236,33 +232,6 @@ class Receipt(object):
msg = self.set_printer()
if 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:
if type_doc in ('invoice', 'quotation') or self._environment == 'retail':
self._print_sale(sale, type_doc, open_box)
@ -271,9 +240,8 @@ class Receipt(object):
except Exception:
pass
self._printer.close()
except Exception as e:
print(str(e))
self.logger.info("Warning: Printer error or device not found!")
except Exception:
logging.exception("Warning: Printer error or device not found!")
def _print_sale(self, sale, type_doc=None, open_box=False):
short = sale['short_invoice']
@ -432,7 +400,7 @@ class Receipt(object):
self._printer.set(align='center')
self._printer.image(self._img_logo, center=True)
self.print_enter()
except:
except Exception:
pass
def print_qrcode(self, qrcode):
@ -440,11 +408,15 @@ class Receipt(object):
self.print_enter()
def print_tasks(self, data):
for value in data.values():
tasks_printed = []
for value in data:
try:
self._printer = None
self.config_printer(value['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']
self._printer.set(custom_size=True, width=2,
height=2, align='center')
@ -453,17 +425,18 @@ class Receipt(object):
height=2, align='left')
self._printer.ln(2)
for ln in value['lines']:
line_ = str(int(ln['qty'])) + ' ' + ln['name']
line_ = str(int(ln['quantity'])) + ' ' + ln['name']
self._printer.textln(line_)
if ln.get('note'):
self._printer.textln('NOTA:' + ln.get('note'))
self._printer.ln(2)
tasks_printed.append(ln['task'])
self._printer.cut()
self._printer.close()
except Exception as e:
print(e)
traceback.print_exc()
except Exception:
logging.exception('error tarea')
time.sleep(1)
return tasks_printed
def print_header(self, short=False):
if not short:
@ -508,9 +481,9 @@ class Receipt(object):
def print_split(self, left, right):
len_left = self._row_characters - len(right) - 1
left = left[:len_left]
if type(left) == bytes:
if isinstance(left, bytes):
left = left.decode("utf-8")
if type(right) == bytes:
if isinstance(right, bytes):
right = right.decode("utf-8")
left += (len_left - len(left) + 1) * ' '
self._printer.text(left)
@ -534,11 +507,11 @@ class Receipt(object):
if self._show_discount and discount and Decimal(discount) > 0:
amount_w_tax = Decimal(line['amount_w_tax'])
discount = Decimal(discount)
initial = 'DCTO - ' + str(round(discount*100, 0)) + '%'
initial = 'DCTO - ' + str(round(discount * 100, 0)) + '%'
if discount == 1:
line_total = 0
else:
line_total = amount_w_tax/(1-discount)
line_total = amount_w_tax / (1 - discount)
discount = '-' + money(line_total - amount_w_tax)
line_total = money(line_total)
@ -547,7 +520,7 @@ class Receipt(object):
length_name = self._row_characters - 11
first_line = code + ' ' + line['name'][:length_name]
if type(first_line) == bytes:
if isinstance(first_line, bytes):
first_line = first_line.decode('utf-8')
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':
self.set_printer()
if not self._printer:
self.logger.info(
logging.info(
"Warning: Interface not found for printer!")
# res.append(None)
return False
self.logger.info("Info: Printer is OK!")
logging.info("Info: Printer is OK!")
try:
self._print_order(order, reversion)
res = self._print_order(order, reversion)
# if True:
res.extend(order['lines_ids'])
except Exception as e:
print(e)
traceback.print_exc()
if res:
res.extend(res)
elif order.get('lines_ids') and True:
res.extend(order['lines_ids'])
except Exception:
logging.exception('error de impresora')
self._printer.close()
time.sleep(1)
except Exception as e:
print(e)
traceback.print_exc()
self.logger.info("Warning: Can not found Printer!")
except Exception:
logging.exception('Can not found Printer!')
return res
def _print_order(self, order, reversion):
lines_printed = []
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._printer.cut()
return True
return lines_printed
def print_body_order(self, order, reversion):
# Exists 2 types of order:
# command => For restaurants kitchens
# dispatch => For external dispatch
lines_printed = []
self._printer.set(font=_FONT_B)
self._printer.set(align='center')
turn = order.get('turn')
@ -994,21 +969,25 @@ class Receipt(object):
def print_lines_order(lines, group=False):
for line in lines:
if self.order_kind == 'command':
self._printer.set(custom_size=True, width=1, height=2)
qty = ' ' + str(int(Decimal(line['quantity'])))
name = line['name']
if group:
name = ' ' + name
self.print_col(qty, self.order_col_1)
self.print_col(name, col_width_name)
if line['note']:
self.print_enter()
for msg_note in line['note'].split('\n'):
self._printer.text(f' NOTA -> {msg_note}')
try:
if self.order_kind == 'command':
self._printer.set(custom_size=True, width=1, height=2)
qty = ' ' + str(int(Decimal(line['quantity'])))
name = line['name']
if group:
name = ' ' + name
self.print_col(qty, self.order_col_1)
self.print_col(name, col_width_name)
if line['note']:
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()
print('este es el camino de la comanda')
self.print_enter()
if isinstance(order['lines'], list):
print_lines_order(order['lines'])
@ -1031,6 +1010,7 @@ class Receipt(object):
self._printer.text(str(order['comment']))
self.print_enter()
self._printer.ln(2)
return lines_printed
# if self._environment != 'retail':
# self._printer.set(custom_size=True, width=2, height=2, align='center')
# title = f'+ + + {_kind} + + +'

View File

@ -27,3 +27,17 @@ def get_screen():
width = screen.width()
height = screen.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'

View File

@ -1 +1 @@
__version__ = "6.0.24"
__version__ = "6.0.25"

20
logger_config.py Normal file
View File

@ -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)