fix print report quotation

add message error when printting not found
This commit is contained in:
Wilson Gomez 2023-08-25 11:37:10 -05:00
parent 45725ea3df
commit b73fb3b7d6
9 changed files with 162 additions and 133 deletions

View File

@ -696,16 +696,18 @@ class DialogGlobalDiscount(QuickDialog):
class DialogPrintInvoice(QuickDialog):
def __init__(self, parent):
options_type = [
('invoice', 'FACTURA'),
('order', 'ORDEN'),
]
if parent.enviroment == 'restaurant':
options_type.append(('quotation', 'COTIZACION'))
view = (
('invoice_number_ask', {'name': 'ORDEN / FACTURA'}),
('type_ask', {
'name': 'TIPO',
'type': 'selection',
'values': [
('invoice', 'FACTURA'),
('order', 'ORDEN'),
('quotation', 'COTIZACION')
],
'values': options_type,
}),
('printer_ask', {
'name': 'IMPRESORA',

View File

@ -71,7 +71,6 @@ class FrontWindow(QMainWindow):
self.screen_size = 'small'
elif self.screen_width <= 1366:
self.screen_size = 'medium'
print('self.screen_size > ', self.screen_size)
self.timeout = _DEFAULT_TIMEOUT
self.setFocus()
@ -96,7 +95,6 @@ class FrontWindow(QMainWindow):
def get_geometry(self):
screen = QGuiApplication.primaryScreen().size()
# screen = QDesktopWidget().screenGeometry()
return screen.width(), screen.height()
def set_style(self, file_css, theme_css=None):
@ -120,14 +118,10 @@ class FrontWindow(QMainWindow):
else:
event.ignore()
def dialog(self, name, response=False, widgets=None, extra_message=None):
kind, msg = self.stack_msg[name]
if extra_message:
print(extra_message)
msg += '\n' + extra_message
# if args:
# msg = msg % args
return QuickDialog(parent=self, kind=kind, string=msg, widgets=widgets)
def set_params(self, values):

View File

@ -1065,7 +1065,10 @@ class AppWindow(FrontWindow):
return
# set type_doc
for i in range(copies):
self.receipt_sale.print_sale(data, type_doc, open_box)
msg = self.receipt_sale.print_sale(data, type_doc, open_box)
if isinstance(msg, dict) and msg.get('error'):
self.dialog('print_error', extra_message=msg['error'])
break
# def button_duplicate_sale(self):
# if self.sale_customer_selected:
@ -2565,7 +2568,6 @@ class AppWindow(FrontWindow):
print('res ....producto creado ...', res)
_add_products()
def create_new_sale(self, kind='take_away'):
if self.type_pos_user == 'cashier':
self.message_bar.set('not_sale')
@ -3087,14 +3089,16 @@ class AppWindow(FrontWindow):
line = self.dialog_product_edit.get()
try:
code = line['product.']['code']
except:
except Exception:
code = line['product']['code']
product = self.Product.find(
[('code', '=', code)],
fields=["code", "description", "extra_tax", "name", "sale_uom",
fields=[
"code", "description", "extra_tax", "name", "sale_uom",
"quantity", "sale_price_w_tax", "template.account_category",
"template.sale_price_w_tax", "template.rec_name",
'products_mix.code', 'products_mix.name', "quantity_mix_required"
'products_mix.code', 'products_mix.name',
"quantity_mix_required"
])
products_mix = product[0].get('products_mix.')
if not products_mix:
@ -3110,7 +3114,7 @@ class AppWindow(FrontWindow):
line = self.dialog_product_edit.get()
try:
code = line['product.']['code']
except:
except Exception:
code = line['product']['code']
product = self.Product.find([('code', '=', code)])
@ -3128,7 +3132,7 @@ class AppWindow(FrontWindow):
def action_print_count_money(self, data):
try:
self.receipt_sale.print_count_money(data)
except:
except Exception:
pass
def action_delete_line(self):
@ -3534,21 +3538,19 @@ class AppWindow(FrontWindow):
self.dialog_delivery_party = DialogDeliveryParty(self).get()
def update_delivery_party(self, field=''):
state_delivery = self.state_delivery_party
if field == 'delivery_party':
self.state_delivery_party['party'] = self.row_delivery_party.text()
if field == 'row_phone':
self.state_delivery_party['phone'] = self.row_phone.text()
if field == 'id_number':
self.state_delivery_party['id_number'] = self.row_id_number.text()
if field == 'number_plate':
self.state_delivery_party['number_plate'] = self.row_number_plate.text(
)
if field == 'type_vehicle':
self.state_delivery_party['type_vehicle'] = self.row_type_vehicle.get_id(
)
if field == 'delivery_party_active':
self.state_delivery_party['active'] = self.row_delivery_party_active.isChecked(
)
state_delivery['party'] = self.row_delivery_party.text()
elif field == 'delivery_party_active':
state_delivery['active'] = self.row_delivery_party_active.isChecked()
elif field == 'row_phone':
state_delivery['phone'] = self.row_phone.text()
elif field == 'id_number':
state_delivery['id_number'] = self.row_id_number.text()
elif field == 'number_plate':
state_delivery['number_plate'] = self.row_number_plate.text()
elif field == 'type_vehicle':
state_delivery['type_vehicle'] = self.row_type_vehicle.get_id()
def search_consumer(self, phone):
if phone:

View File

@ -31,10 +31,10 @@ MODELS_RESTAURANT = {
'payment_term.rec_name', 'payments', 'tip_amount',
'total_amount', 'residual_amount', 'paid_amount', 'untaxed_amount',
'tax_amount', 'delivery_charge', 'price_list', 'invoice_number',
'shipment_address', 'kind', 'shop', 'order_status',
'shipment_address', 'kind', 'shop', 'order_status',
'delivery_party', 'reference', 'comment', 'payment_method',
'delivery_state', 'table_assigned.name', 'invoice_type', 'net_amount',
'delivery_amount',
'delivery_state', 'table_assigned.name', 'invoice_type',
'net_amount', 'delivery_amount',
'source.rec_name', 'position', 'payment_term.payment_type',
'consumer.name', 'consumer.phone', 'consumer.rec_name',
'consumer.address', 'consumer.notes', 'consumer.delivery',
@ -82,7 +82,7 @@ MODELS_RESTAURANT = {
'fields': [
'id', 'name', 'party', 'party.invoice_address',
'party.shipment_address'
]
]
},
'party.consumer': {
'rec_name': 'rec_name',
@ -97,8 +97,9 @@ MODELS_RESTAURANT = {
'sale.device': {
'rec_name': 'name',
'fields': [
'name', 'shop.company', 'shop.name', 'shop.taxes', 'shop.taxes.name',
'shop.party.name', 'journals.name', 'journals.require_voucher', 'journals.kind',
'name', 'shop.company', 'shop.name', 'shop.taxes',
'shop.party.name', 'journals.name', 'journals.require_voucher',
'journals.kind', 'shop.taxes.name',
'shop.product_categories.accounting',
'shop.product_categories.name',
'shop.product_categories.name_icon',
@ -116,16 +117,17 @@ MODELS_RESTAURANT = {
'shop.product_categories.childs.products.name',
'shop.product_categories.childs.products.code',
'shop.product_categories.childs.products.products_mix',
'journal.name',
'journal.kind',
'journal.name', 'journal.kind',
'journal.require_voucher',
'shop.payment_term.name', 'shop.warehouse', 'shop.discount_pos_method',
'shop.payment_term.name', 'shop.warehouse',
'shop.salesman_pos_required', 'shop.electronic_authorization',
'shop.invoice_copies', 'shop.pos_authorization', 'shop.discounts',
'shop.computer_authorization', 'shop.manual_authorization',
'shop.credit_note_electronic_authorization', 'shop.salesmans.rec_name',
'shop.debit_note_electronic_authorization', 'shop.delivery_man.active',
'shop.delivery_man.rec_name', 'shop.price_list.name', 'shop.order_copies'
'shop.credit_note_electronic_authorization',
'shop.salesmans.rec_name', 'shop.discount_pos_method',
'shop.debit_note_electronic_authorization',
'shop.delivery_man.rec_name', 'shop.price_list.name',
'shop.order_copies', 'shop.delivery_man.active',
]
},
'sale.shop': {
@ -151,8 +153,8 @@ MODELS_RESTAURANT = {
'fields': [
'name', 'id_number', 'addresses.street', 'phone',
'customer_payment_term.name', 'customer_payment_term.payment_type',
'credit_limit_amount', 'receivable',
'salesman', 'credit_amount', 'street', 'invoice_type'
'credit_limit_amount', 'receivable',
'salesman', 'credit_amount', 'street', 'invoice_type'
]
},
'ir.action.report': {
@ -171,7 +173,7 @@ MODELS_RESTAURANT = {
'print_invoice_payment', 'encoded_sale_price',
'delivery_product.list_price', 'delivery_product.code',
'delivery_product.name', 'allow_discount_handle',
'cache_products_local', 'show_party_categories',
'cache_products_local', 'show_party_categories',
'print_lines_product', 'uvt_pos'
]
},
@ -299,7 +301,7 @@ MODELS_RETAIL = {
'fields': [
'id', 'name', 'party', 'party.invoice_address',
'party.shipment_address'
]
]
},
'party.consumer': {
'rec_name': 'rec_name',
@ -314,8 +316,9 @@ MODELS_RETAIL = {
'sale.device': {
'rec_name': 'name',
'fields': [
'name', 'shop.company', 'shop.name', 'shop.taxes', 'shop.taxes.name',
'shop.party.name', 'journals.name', 'journals.require_voucher', 'journals.kind',
'name', 'shop.company', 'shop.name', 'shop.taxes',
'shop.party.name', 'journals.name', 'journals.require_voucher',
'journals.kind', 'shop.taxes.name',
'shop.product_categories.accounting',
'shop.product_categories.name',
'shop.product_categories.name_icon',
@ -332,14 +335,16 @@ MODELS_RETAIL = {
'shop.product_categories.childs.products.name',
'shop.product_categories.childs.products.code',
'journal.name', 'journal.require_voucher',
'journal.kind',
'shop.payment_term.name', 'shop.warehouse', 'shop.discount_pos_method',
'journal.kind', 'shop.discount_pos_method',
'shop.payment_term.name', 'shop.warehouse',
'shop.salesman_pos_required', 'shop.electronic_authorization',
'shop.invoice_copies', 'shop.pos_authorization', 'shop.discounts',
'shop.computer_authorization', 'shop.manual_authorization',
'shop.credit_note_electronic_authorization', 'shop.salesmans.rec_name',
'shop.debit_note_electronic_authorization', 'shop.delivery_man.active',
'shop.delivery_man.rec_name', 'shop.price_list.name', 'shop.order_copies'
'shop.credit_note_electronic_authorization',
'shop.salesmans.rec_name', 'shop.delivery_man.active',
'shop.debit_note_electronic_authorization',
'shop.delivery_man.rec_name', 'shop.price_list.name',
'shop.order_copies'
]
},
'sale.shop': {
@ -364,8 +369,8 @@ MODELS_RETAIL = {
'fields': [
'name', 'id_number', 'addresses.street', 'phone',
'customer_payment_term.name', 'customer_payment_term.payment_type',
'credit_limit_amount', 'receivable',
'salesman', 'credit_amount', 'street', 'invoice_type'
'credit_limit_amount', 'receivable',
'salesman', 'credit_amount', 'street', 'invoice_type'
]
},
'ir.action.report': {
@ -384,7 +389,7 @@ MODELS_RETAIL = {
'print_invoice_payment', 'encoded_sale_price',
'delivery_product.list_price', 'delivery_product.code',
'delivery_product.name', 'allow_discount_handle',
'cache_products_local', 'show_party_categories',
'cache_products_local', 'show_party_categories',
'print_lines_product', 'uvt_pos'
]
},

View File

@ -1,19 +1,19 @@
# import ssl
import os
import base64
import tempfile
import ssl
from datetime import date
from decimal import Decimal
from http.client import HTTPConnection, HTTPSConnection
import orjson as json
try:
from app.models import MODELS_RESTAURANT, MODELS_RETAIL
except:
except Exception:
from models import MODELS_RESTAURANT, MODELS_RETAIL
try:
from app.commons.common import slugify, file_open
except:
except Exception:
from commons.common import slugify, file_open
from app.commons.dblogin import context_http
@ -37,6 +37,7 @@ 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']
@ -46,12 +47,11 @@ def logout(ctx):
else:
conn = HTTPSConnection(host, port=port, context=context_http)
url = '/' + db + '/logout'
payload = json.dumps({'context': {
'session':ctx.get('session'),
'login': ctx.get('login')
}}
,
default=encoder)
payload = json.dumps({
'context': {
'session': ctx.get('session'),
'login': ctx.get('login')}
}, default=encoder)
conn.request('POST', url, body=payload, headers=HEADERS)
response = conn.getresponse()
if response.status != 200:
@ -111,7 +111,7 @@ class Model(object):
}
res = self.get_connection('POST', '/search', args_)
return res
def fields_get(self, fields=[]):
if not fields:
fields = self.fields
@ -161,7 +161,7 @@ class Model(object):
}
res = self.get_connection('POST', '/create', args_)
return res
def method_instance(self, method, instance):
args_ = {
'model': self.model,
@ -188,7 +188,10 @@ class Model(object):
else:
payload = None
if self.context_http:
conn = self.conn(self.host, port=self.port, context=self.context_http)
conn = self.conn(
self.host,
port=self.port,
context=self.context_http)
else:
conn = self.conn(self.host, port=self.port)
conn.request(method, url, body=payload, headers=HEADERS)
@ -197,7 +200,9 @@ class Model(object):
if response.status != 200:
if self.main_window:
print(res, 'valida')
self.main_window.dialog('error_server', extra_message=res['detail']['error'])
self.main_window.dialog(
'error_server',
extra_message=res['detail']['error'])
res = res['detail']
conn.close()
return res

View File

@ -6,6 +6,7 @@ import logging
import traceback
from datetime import datetime
from decimal import Decimal
import subprocess
from .printing.protocols import FileSSH
@ -178,11 +179,33 @@ class Receipt(object):
self._device = device
self._profile = printer['profile']
def check_status(self, interface, device):
status = False
if interface == "network":
command = "ping -c 1 " if OS_NAME == 'posix' else "ping -n 1"
response = subprocess.call(str(command + device).split(" "))
if response == 0:
status = True
elif interface == "usb":
if OS_NAME == 'posix':
status = os.path.exists(device)
elif OS_NAME == 'nt':
status = True
return status
def set_printer(self):
try:
status = self.check_status(self._interface, self._device)
if not status:
msg = f'''
Impresora no esta disponible;
revisa la configuracion o conexion de impresora
interface: {self._interface}, device: {self._device}
'''
print(msg)
return msg
if self._interface == 'usb':
if OS_NAME == 'posix':
print()
self._printer = printer.File(
self._device, profile=self._profile)
elif OS_NAME == 'nt':
@ -191,68 +214,68 @@ class Receipt(object):
elif self._interface == 'network':
try:
host, port = self._device.split(":")
except:
except Exception:
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)
# 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:
msg = "Warning: Can not found Printer!"
self.logger.info("Warning: Can not found Printer!")
return
return msg
self.logger.info("Info: Printer is OK!")
except:
except Exception as e:
traceback.print_exc()
self.logger.info("Warning: Printer error or device not found!")
def validate_printer(self, _interface, ):
return
self.logger.info(
"Warning: Printer error or device not found!", str(e))
def print_sale(self, sale, type_doc=None, open_box=False):
try:
# if call this function we can ommit line 216 to 238
# self.set_printer()
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!")
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)
else:
self._print_sale_verification(sale)
except:
except Exception:
pass
self._printer.close()
except Exception as e:
@ -266,21 +289,18 @@ class Receipt(object):
if not short:
if sale.get('cufe'):
self._printer.text('CUFE: ' + sale['cufe'])
try:
if sale.get('qr_code'):
self.print_qrcode(sale['qr_code'])
except:
pass
if sale.get('qr_code'):
self.print_qrcode(sale['qr_code'])
self.print_footer(open_box, type_doc)
else:
self._printer.cut()
# self.print_extra_info(sale)
if self._interface == 'cups':
self._file.close()
self.conn.printFile(self._printer_name, TEMP_INVOICE_FILE,
'POS Invoice', {})
else:
self._printer.close()
# if self._interface == 'cups':
# self._file.close()
# self.conn.printFile(self._printer_name, TEMP_INVOICE_FILE,
# 'POS Invoice', {})
# else:
# self._printer.close()
def _print_sale_verification(self, sale):
self.print_header_sale_verification(sale)
@ -838,7 +858,7 @@ class Receipt(object):
elif order['interface'] == 'network':
try:
host, port = host.split(":")
except:
except Exception:
host, port = host, None
if port:
self._printer = printer.Network(host, port=int(port), timeout=15)
@ -862,10 +882,10 @@ class Receipt(object):
self.logger.info("Info: Printer is OK!")
try:
res.append(self._print_order(order, reversion))
except:
except Exception:
pass
self._printer.close()
except:
except Exception:
self.logger.info("Warning: Can not found Printer!")
res.append(None)
return all(res)

View File

@ -26,7 +26,7 @@ class StackMessages(QWidget):
'missing_agent': ('warning', 'FALTA EL AGENTE!'),
'missing_salesman': ('warning', 'NO HAY VENDEDOR EN LA VENTA!'),
'sale_without_products': ('warning', 'NO PUEDE CONFIRMAR VENTA SIN PRODUCTOS!'),
'user_without_permission': ('error', 'USUARIO SIN PERMISOS DE VENTAS!'),
# 'user_without_permission': ('error', 'USUARIO SIN PERMISOS DE VENTAS!'),
'quantity_not_valid': ('error', 'LA CANTIDAD NO ES VALIDA...!'),
'user_not_permissions_device': ('error', 'EL USUARIO NO TIENE PERMISOS DE ACCESO!'),
'missing_party_configuration': ('warning', 'FALTA CONFIGURAR EL TERCERO POR DEFECTO!'),
@ -69,4 +69,5 @@ class StackMessages(QWidget):
'confirm_agent': ('question', 'Confirmar comision de agente'),
'qty_combo_min_req': ('error', 'Cantidad minima requerida!'),
'error_server': ('error', 'Error'),
'print_error': ('error', 'Error de Impresión')
}

View File

@ -1 +1 @@
__version__ = "6.0.17"
__version__ = "6.0.18"

View File

@ -3,7 +3,7 @@ server=localhost
port=8010
# options http or https
mode=http
database=DEMO
database=DBNAME
user=admin
#########################################