refactory code in app pos

This commit is contained in:
Wilson Gomez 2023-10-12 10:57:17 -05:00
parent e94a7c868c
commit 50739286d6
26 changed files with 649 additions and 4060 deletions

16
INSTALL
View File

@ -13,7 +13,6 @@ On Debian, Ubuntu and Derivatives, it is recommended to use: $ apt install packa
* Python 3.10 or later (http://www.python.org/) * Python 3.10 or later (http://www.python.org/)
* python-setuptools * python-setuptools
* python3-pySide6
* python3-dateutil * python3-dateutil
* python3-pip * python3-pip
* libusb-1.0-0 * libusb-1.0-0
@ -24,18 +23,15 @@ On Debian, Ubuntu and Derivatives, it is recommended to use: $ apt install packa
* python3-dev * python3-dev
* python3-pil * python3-pil
* neo (https://bitbucket.org/presik/neox)
The following packages must be installed using PIP The following packages must be installed using PIP
pip3 install pyusb pip3 install pyusb
pip3 install pillow pip3 install pillow
pip3 install qrcode pip3 install qrcode
pip3 install paramiko pip3 install paramiko
pip3 install pycups pip3 install orjson
pip3 install requests
pip3 install simplejson
pip3 install escpos pip3 install escpos
pip3 install PySide6
For Windows add: For Windows add:
@ -170,14 +166,6 @@ This last one is optional if applicable.
POS CLIENT INSTALLATION AND CONFIGURATION POS CLIENT INSTALLATION AND CONFIGURATION
---------------------------------------------------------------------------- ----------------------------------------------------------------------------
POS Client Requirements:
* libjpeg8
* libjpeg62-dev
* libfreetype6
* libfreetype6-dev
Download the POS Client, using the hg clone command: Download the POS Client, using the hg clone command:
https://bitbucket.org/presik/presik_pos https://bitbucket.org/presik/presik_pos

View File

@ -1,7 +1,7 @@
Instalación de Tryton POS Client Qt5 Instalación de Tryton POS Client Qt5
==================================== ====================================
Esta versión solo es compatible con Tryton 5.0+, se asume que el usuario tiene Esta versión solo es compatible con Tryton 6.0+, se asume que el usuario tiene
conocimientos básicos previos sobre la instalación y configuración de Tryton, conocimientos básicos previos sobre la instalación y configuración de Tryton,
especialmente los modulos oficiales relacionados con contabilidad y ventas, no especialmente los modulos oficiales relacionados con contabilidad y ventas, no
es el objeto de esta guia abordar temas de configuración básica. es el objeto de esta guia abordar temas de configuración básica.
@ -11,10 +11,8 @@ paquetes instalados en el sistema:
En Debian, Ubuntu y Derivados, se recomienda usar: $ apt install paquete En Debian, Ubuntu y Derivados, se recomienda usar: $ apt install paquete
* Python 3.7 or later (http://www.python.org/) * Python 3.10 or later (http://www.python.org/)
* python-setuptools * python-setuptools
* python3-pyqt5
* python3-pyqt5.qtsvg
* python3-dateutil * python3-dateutil
* python3-pip * python3-pip
* libusb-1.0-0 * libusb-1.0-0
@ -35,7 +33,7 @@ Los siguientes paquetes se deben instalar usando PIP
pip3 install paramiko pip3 install paramiko
pip3 install orjson pip3 install orjson
pip3 install escpos pip3 install escpos
pip3 install PySide6>=6.4.1 pip3 install PySide6
Tener en cuenta que algunos paquetes se deben instalar con pip para python3. Tener en cuenta que algunos paquetes se deben instalar con pip para python3.
@ -43,7 +41,7 @@ Tener en cuenta que algunos paquetes se deben instalar con pip para python3.
Nota: el Cliente POS de momento ha sido testeado en Windows parcialmente, asi que Nota: el Cliente POS de momento ha sido testeado en Windows parcialmente, asi que
no hay garantia de que funcione al 100% en este OS. no hay garantia de que funcione al 100% en este OS.
Se recomienda instalar Tryton 5.0 creando un ambiente virtual con Se recomienda instalar Tryton 6.0 creando un ambiente virtual con
virtualenv. virtualenv.
Los siguientes módulos se deben instalar en la base de datos Tryton Los siguientes módulos se deben instalar en la base de datos Tryton
@ -84,6 +82,7 @@ Modulos No Oficiales (Presik)
* trytonpsk_sale_salesman (https://bitbucket.org/presik/trytonpsk_sale_salesman) * trytonpsk_sale_salesman (https://bitbucket.org/presik/trytonpsk_sale_salesman)
* trytonpsk_sale_discount (https://bitbucket.org/presik/trytonpsk_sale_discount) * trytonpsk_sale_discount (https://bitbucket.org/presik/trytonpsk_sale_discount)
* trytonpsk_sale_pos_frontend (https://bitbucket.org/presik/trytonpsk_sale_pos_frontend) * trytonpsk_sale_pos_frontend (https://bitbucket.org/presik/trytonpsk_sale_pos_frontend)
* trytonpsk_sale_co (https://bitbucket.org/presik/trytonpsk_sale_co
Ingresar al directorio e instalar (dentro del ambiente virtual Ingresar al directorio e instalar (dentro del ambiente virtual
anteriormente creado): anteriormente creado):
@ -165,14 +164,6 @@ Este último es opcional si es aplica.
INSTALACION Y CONFIGURACION DEL CLIENTE POS INSTALACION Y CONFIGURACION DEL CLIENTE POS
---------------------------------------------------------------------------- ----------------------------------------------------------------------------
Requisitos del Cliente POS:
* libjpeg8
* libjpeg62-dev
* libfreetype6
* libfreetype6-dev
Instalelos con: apt-get install paquete Instalelos con: apt-get install paquete
Ahora se debe descargar e instalar el modulo python_escpos, el cual Ahora se debe descargar e instalar el modulo python_escpos, el cual
@ -283,7 +274,7 @@ Haga una venta desde Tryton sin POS
----------------------------------- -----------------------------------
Asi que en este punto sin necesidad del Cliente POS usted debería ser Asi que en este punto sin necesidad del Cliente POS usted debería ser
capaz a través del cliente Tryton 5.0, de hacer ventas: capaz a través del cliente Tryton 6.0, de hacer ventas:
>> Ventas > Ventas POS >> Ventas > Ventas POS

2
README
View File

@ -2,7 +2,7 @@ Presik POS Client for Tryton
========================================= =========================================
The Point of Sale Client for Tryton application platform development The Point of Sale Client for Tryton application platform development
in Qt5 and Python3. in Qt5(PySide6) and Python3.
Installing Installing
---------- ----------

View File

@ -44,7 +44,7 @@ class StartButtons(QVBoxLayout):
['button_start_take_away', 'PARA LLEVAR', 'action_start_take_away', 'take_away'], ['button_start_take_away', 'PARA LLEVAR', 'action_start_take_away', 'take_away'],
['button_start_delivery', 'DOMICILIO', 'action_start_delivery', 'delivery'], ['button_start_delivery', 'DOMICILIO', 'action_start_delivery', 'delivery'],
]) ])
if parent.enviroment == 'restaurant': if parent.environment == 'restaurant':
values_extend([ values_extend([
['button_start_table', 'A LA MESA', 'action_start_table', 'table'], ['button_start_table', 'A LA MESA', 'action_start_table', 'table'],
['button_start_catering', 'CATERING', 'action_start_catering', 'catering'], ['button_start_catering', 'CATERING', 'action_start_catering', 'catering'],
@ -54,7 +54,7 @@ class StartButtons(QVBoxLayout):
['button_print_sale', 'IMPRIMIR', 'action_print_sale', 'print_sale'], ['button_print_sale', 'IMPRIMIR', 'action_print_sale', 'print_sale'],
]) ])
if parent.enviroment == 'restaurant': if parent.environment == 'restaurant':
values_extend([ values_extend([
['button_tables', 'VER MESAS', 'action_tables', 'tables'] ['button_tables', 'VER MESAS', 'action_tables', 'tables']
]) ])
@ -70,7 +70,7 @@ class StartButtons(QVBoxLayout):
['button_reports', 'REPORTES', 'action_reports', 'reports'], ['button_reports', 'REPORTES', 'action_reports', 'reports'],
['button_historic_sales', 'HISTORIAL', 'action_historic_sales', 'sales_history'], ['button_historic_sales', 'HISTORIAL', 'action_historic_sales', 'sales_history'],
]) ])
if parent.enviroment == 'retail': if parent.environment == 'retail':
values_extend([ values_extend([
['button_collection', 'RECAUDO', 'action_collection', 'collection'] ['button_collection', 'RECAUDO', 'action_collection', 'collection']
]) ])
@ -104,7 +104,7 @@ class ButtonsFunction(QGridLayout):
self.setVerticalSpacing(2) self.setVerticalSpacing(2)
self.parent = parent self.parent = parent
self.set_values(values) self.set_values(values)
if self.parent.enviroment == 'restaurant': if self.parent.environment == 'restaurant':
rows = 3 rows = 3
columns = 5 columns = 5
name_style = 'toolbar' name_style = 'toolbar'
@ -144,7 +144,7 @@ class ButtonsFunction(QGridLayout):
['button_advance', 'ANTICIPO', 'action_add_advance'], ['button_advance', 'ANTICIPO', 'action_add_advance'],
]) ])
if self.parent.enviroment == 'restaurant': if self.parent.environment == 'restaurant':
rest_options = [ rest_options = [
['button_delivery', 'AGREGAR DOMICILIO', 'action_delivery'], ['button_delivery', 'AGREGAR DOMICILIO', 'action_delivery'],
['button_comment', 'NOTA', 'action_comment'], ['button_comment', 'NOTA', 'action_comment'],
@ -250,7 +250,7 @@ class ButtonsStacked(QWidget):
hbox.addWidget(self.stacked, 0) hbox.addWidget(self.stacked, 0)
if pos_user in ('cashier', 'frontend_admin'): if pos_user in ('cashier', 'frontend_admin'):
hbox.addWidget(self.button_payment_term, 0) hbox.addWidget(self.button_payment_term, 0)
if parent.enviroment == 'retail': if parent.environment == 'retail':
if pos_user == 'cashier' and getattr(parent, 'button_to_draft_active', None): if pos_user == 'cashier' and getattr(parent, 'button_to_draft_active', None):
self.button_to_draft = CustomButton( self.button_to_draft = CustomButton(
id='button_to_draft', id='button_to_draft',

View File

@ -33,9 +33,37 @@ class Params(object):
config_file = self.file config_file = self.file
settings = QSettings(config_file, QSettings.IniFormat) settings = QSettings(config_file, QSettings.IniFormat)
self.params = {
self.params = {} "server": "localhost",
"port": "8010",
"mode": "http",
"database": "DBNAME",
"user": None,
"printer_sale_name": None,
"profile_printer": "TM-P80",
"row_characters": "48",
"print_receipt": "manually", # manually or automatic
"active_weighing": False,
"print_order": False,
"print_auto_order": False,
"auto_print_commission": False,
"button_to_draft_active": False,
"server_printer": False,
"active_timeout": True,
"tasks_station": True,
"timeout": 10000,
"tablet_mode": False,
"theme": "base",
"mode_window": "maximized",
"locale": "es_CO.UTF-8",
"language": "es_CO",
"environment": "retail",
"profile_name": "MY DEMO"
}
for key in settings.allKeys(): for key in settings.allKeys():
if key[0] == '#': if key[0] == '#':
continue continue
if key == 'enviroment': # for remove this condition
self.params['environment'] = settings.value(key, None)
else:
self.params[key] = settings.value(key, None) self.params[key] = settings.value(key, None)

View File

@ -65,7 +65,6 @@ class CustomButton(QPushButton):
css_file = os.path.join(root_dir, 'css', css_screens[size]) css_file = os.path.join(root_dir, 'css', css_screens[size])
with open(css_file, 'r') as infile: with open(css_file, 'r') as infile:
styles.append(infile.read()) styles.append(infile.read())
self.setStyleSheet(''.join(styles)) self.setStyleSheet(''.join(styles))
if name_style == 'start': if name_style == 'start':
self.setObjectName('button_start') self.setObjectName('button_start')

View File

@ -169,7 +169,7 @@ def xconnection(mode, user, password, host, database, port):
res = json.loads(response.read()) res = json.loads(response.read())
if not res.get('status'): if not res.get('status'):
res['status'] = response.status res['status'] = response.status
except: except Exception:
status = status status = status
msg = '' msg = ''
if response: if response:

View File

@ -222,8 +222,8 @@ class FieldMoney(QLineEdit):
if not amount: if not amount:
self.zero() self.zero()
def __str__(self): # def __str__(self):
return self.format_text() # return self.format_text()
def format_text(self, text_): def format_text(self, text_):
amount = float(text_) amount = float(text_)
@ -483,7 +483,7 @@ class GridForm(QGridLayout):
expand = 1 expand = 1
if type_ == 'text': if type_ == 'text':
align = 'left' align = 'left'
except: except Exception:
_field = Field(obj, key, value, form=self) _field = Field(obj, key, value, form=self)
if value.get('password') is True: if value.get('password') is True:
_field.setEchoMode(QLineEdit.Password) _field.setEchoMode(QLineEdit.Password)

View File

@ -116,7 +116,7 @@ class MenuDash(QWidget):
try: try:
new_view = self.ctx_widgets[view_id]['items'] new_view = self.ctx_widgets[view_id]['items']
new_view.show() new_view.show()
except: except Exception:
return return
self.main.addWidget(new_view) self.main.addWidget(new_view)
@ -145,10 +145,7 @@ class MenuDash(QWidget):
} }
main_cat_addWidget = self.main_categories.addWidget main_cat_addWidget = self.main_categories.addWidget
for value in self.values: for value in self.values:
# print(value, type(value['id']))
cat_id = str(value['id']) cat_id = str(value['id'])
# if not value:
# continue
if col_cat > num_cat_cols - 1: if col_cat > num_cat_cols - 1:
col_cat = 0 col_cat = 0
row_cat += 1 row_cat += 1
@ -263,10 +260,9 @@ class GridButtons(QWidget):
self.set_items() self.set_items()
def create_list_items(self): def create_list_items(self):
self.list_items, button_size, style = [], self.button_size, self.style button_size, style = self.button_size, self.style
list_items_append = self.list_items.append self.list_items = [
for value in self.values: CustomButton(
_button = CustomButton(
parent=self, parent=self,
id=value['id'], id=value['id'],
desc_extractor='name', desc_extractor='name',
@ -275,7 +271,8 @@ class GridButtons(QWidget):
size=button_size, size=button_size,
name_style=style, name_style=style,
) )
list_items_append(_button) for value in self.values
]
def action_selected(self, idx): def action_selected(self, idx):
self.action(idx) self.action(idx)

View File

@ -132,7 +132,7 @@ class SearchWindow(QDialog):
self.filter_layout.addWidget(self.label_control) self.filter_layout.addWidget(self.label_control)
def set_counter_control(self, val): def set_counter_control(self, val):
self.label_control.setText(str(len(val))) self.label_control.setText(str(val))
def set_from_objects(self, objects): def set_from_objects(self, objects):
self.rows = [] self.rows = []

View File

@ -73,7 +73,7 @@ MONEY = [
SALE_FIELDS = [ SALE_FIELDS = [
'number', 'party', 'sale_date', 'comment', 'position', 'number', 'party', 'sale_date', 'comment', 'position',
'description', 'invoice_number', 'tip_amount', 'delivery_amount', 'description', 'invoice_number', 'tip_amount', 'delivery_amount',
'salesman', 'state', 'kind', 'channel', 'reference', 'salesman', 'state', 'kind', 'reference',
'invoice_type', 'consumer', 'delivery_party', 'table_assigned' 'invoice_type', 'consumer', 'delivery_party', 'table_assigned'
] ]

View File

@ -230,7 +230,7 @@ class SearchSale(SearchWindow):
size='mini_button', size='mini_button',
) )
if self.parent.enviroment == 'restaurant': if self.parent.environment == 'restaurant':
self.pushButtonReservation = CustomButton( self.pushButtonReservation = CustomButton(
id='button_search_sale_reservation', id='button_search_sale_reservation',
parent=self, parent=self,
@ -320,7 +320,7 @@ class SearchProduct(SearchWindow):
headers['template.brand.name'] = {'desc': 'MARCA', 'type': 'char'} headers['template.brand.name'] = {'desc': 'MARCA', 'type': 'char'}
_cols_width_append(100) _cols_width_append(100)
if parent.enviroment == 'retail': if parent.environment == 'retail':
headers['template.reference'] = {'desc': 'REFERENCIA', 'type': 'char'} headers['template.reference'] = {'desc': 'REFERENCIA', 'type': 'char'}
_cols_width_append(200) _cols_width_append(200)
@ -639,7 +639,7 @@ class DialogAgent(QuickDialog):
'domain': [], 'domain': [],
'fields': [ 'fields': [
('id', 'ID'), ('id', 'ID'),
('party.rec_name', 'NOMBRE'), ('party.name', 'NOMBRE'),
('party.id_number', 'NUMERO ID'), ('party.id_number', 'NUMERO ID'),
] ]
}), }),
@ -700,7 +700,7 @@ class DialogPrintInvoice(QuickDialog):
('invoice', 'FACTURA'), ('invoice', 'FACTURA'),
('order', 'ORDEN'), ('order', 'ORDEN'),
] ]
if parent.enviroment == 'restaurant': if parent.environment == 'restaurant':
options_type.append(('quotation', 'COTIZACION')) options_type.append(('quotation', 'COTIZACION'))
view = ( view = (
('invoice_number_ask', {'name': 'ORDEN / FACTURA'}), ('invoice_number_ask', {'name': 'ORDEN / FACTURA'}),
@ -817,7 +817,7 @@ class DeliveryPartySelected(QuickDialog):
parent.row_delivery_party = QLineEdit() parent.row_delivery_party = QLineEdit()
parent.row_delivery_party.setObjectName('row_delivery_party') parent.row_delivery_party.setObjectName('row_delivery_party')
parent.row_delivery_party.textChanged.connect( parent.row_delivery_party.textChanged.connect(
lambda: parent.update_delivery_party('delivery_party')) lambda: parent.update_delivery_party('party'))
grid.addWidget(parent.row_delivery_party, 1, 2) grid.addWidget(parent.row_delivery_party, 1, 2)
label_id_number = QLabel('NUMERO ID:') label_id_number = QLabel('NUMERO ID:')
@ -847,7 +847,7 @@ class DeliveryPartySelected(QuickDialog):
parent.row_phone = QLineEdit() parent.row_phone = QLineEdit()
parent.row_phone.setObjectName('row_phone') parent.row_phone.setObjectName('row_phone')
parent.row_phone.textChanged.connect( parent.row_phone.textChanged.connect(
lambda: parent.update_delivery_party('row_phone')) lambda: parent.update_delivery_party('phone'))
grid.addWidget(parent.row_phone, 4, 2) grid.addWidget(parent.row_phone, 4, 2)
label_type_vehicle = QLabel('TIPO DE VEHICULO:') label_type_vehicle = QLabel('TIPO DE VEHICULO:')
@ -868,7 +868,7 @@ class DeliveryPartySelected(QuickDialog):
parent.row_delivery_party_active = QCheckBox() parent.row_delivery_party_active = QCheckBox()
parent.row_delivery_party_active.setObjectName('row_delivery_party_active') parent.row_delivery_party_active.setObjectName('row_delivery_party_active')
parent.row_delivery_party_active.stateChanged.connect( parent.row_delivery_party_active.stateChanged.connect(
lambda: parent.update_delivery_party('delivery_party_active')) lambda: parent.update_delivery_party('active'))
grid.addWidget(parent.row_delivery_party_active, 6, 2) grid.addWidget(parent.row_delivery_party_active, 6, 2)
vbox_.addLayout(grid) vbox_.addLayout(grid)
@ -1179,7 +1179,7 @@ class TipAmount(QuickDialog):
label_tip_amount_ask.setObjectName('label_tip_amount_ask') label_tip_amount_ask.setObjectName('label_tip_amount_ask')
grid.addWidget(label_tip_amount_ask, 1, 1) grid.addWidget(label_tip_amount_ask, 1, 1)
parent.field_tip_amount_ask = QLineEdit() parent.field_tip_amount_ask = QLineEdit()
parent.field_tip_amount_ask.setObjectName('field_delivery_amount_ask') parent.field_tip_amount_ask.setObjectName('field_tip_amount_ask')
grid.addWidget(parent.field_tip_amount_ask, 1, 2) grid.addWidget(parent.field_tip_amount_ask, 1, 2)
vbox_.addLayout(grid) vbox_.addLayout(grid)
parent.field_tip_amount_invoice = QCheckBox() parent.field_tip_amount_invoice = QCheckBox()
@ -1335,7 +1335,7 @@ class ProductEdit(QuickDialog):
self.checkbox_base.setText('PRECIO BASE') self.checkbox_base.setText('PRECIO BASE')
self.checkbox_base.setMaximumSize(120, 0) self.checkbox_base.setMaximumSize(120, 0)
if parent.enviroment == 'restaurant': if parent.environment == 'restaurant':
hbox.addWidget(button_discounts_bono, 0) hbox.addWidget(button_discounts_bono, 0)
hbox.addWidget(button_combo, 0) hbox.addWidget(button_combo, 0)
hbox.addWidget(button_addition, 0) hbox.addWidget(button_addition, 0)

View File

@ -172,7 +172,7 @@ class FrontWindow(QMainWindow):
self.dialog_info_product = DialogInfoProduct(self) self.dialog_info_product = DialogInfoProduct(self)
if self._commission_activated: if self._commission_activated:
self.dialog_agent = DialogAgent(self) self.dialog_agent = DialogAgent(self)
if self.enviroment == 'restaurant' and self._sale_pos_restaurant: if self.environment == 'restaurant' and self._sale_pos_restaurant:
self.dialog_combine_product = CombineProduct(self) self.dialog_combine_product = CombineProduct(self)
self.dialog_combo_product = DialogComboProduct(self) self.dialog_combo_product = DialogComboProduct(self)
self.dialog_historic_sales = DialogHistoricSales(self) self.dialog_historic_sales = DialogHistoricSales(self)
@ -209,7 +209,7 @@ class FrontWindow(QMainWindow):
self.discount_method = self._config.get('discount_pos_method') self.discount_method = self._config.get('discount_pos_method')
self.allow_discount_handle = self._config.get('allow_discount_handle', None) self.allow_discount_handle = self._config.get('allow_discount_handle', None)
self.sale_automatic = False self.sale_automatic = False
if self.enviroment == 'retail' and self._config.get('new_sale_automatic'): if self.environment == 'retail' and self._config.get('new_sale_automatic'):
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
@ -218,38 +218,29 @@ class FrontWindow(QMainWindow):
('state', '=', 'activated'), ('state', '=', 'activated'),
]) ])
_product = { # _product = {
'name': 'product.product', # 'name': 'product.product',
'fields': [ # 'fields': [
'template.name', 'code', 'write_date', # 'template.name', 'code', 'write_date',
'description', 'template.sale_price_w_tax', # 'description', 'template.sale_price_w_tax',
'template.account_category' # 'template.account_category'
] # ]
} # }
# self.cache_local = self._config.get('cache_products_local') # # self.cache_local = self._config.get('cache_products_local')
if self._config['show_location_pos']: # if self._config['show_location_pos']:
_product['fields'].append('location_') # _product['fields'].append('location_')
if self._config['show_stock_pos'] in ('value', 'icon'): # if self._config['show_stock_pos'] in ('value', 'icon'):
if self._config['show_stock_pos'] == 'value': # if self._config['show_stock_pos'] == 'value':
_product['fields'].append('quantity') # _product['fields'].append('quantity')
if self._config['show_brand']: # if self._config['show_brand']:
_product['fields'].append('template.brand.name') # _product['fields'].append('template.brand.name')
if self._config['encoded_sale_price']: # if self._config['encoded_sale_price']:
_product['fields'].extend( # _product['fields'].extend(
['image', 'image_icon', 'encoded_sale_price']) # ['image', 'image_icon', 'encoded_sale_price'])
if self.enviroment == 'restaurant':
self._sale_pos_restaurant = self.Module.find([
('name', '=', 'sale_pos_frontend_rest'),
('state', '=', 'activated'),
])
if self._sale_pos_restaurant:
self.PartyConsumer = Model('party.consumer', self.ctx)
if self._config['delivery_product.']:
self._delivery_product = 0
self.User = Model('res.user', self.ctx, main_window=self) self.User = Model('res.user', self.ctx, main_window=self)
self._user, = self.User.find([('login', '=', self.user)]) self._user, = self.User.find([('login', '=', self.user)])
self.Company = Model('company.company', self.ctx, main_window=self) self.Company = Model('company.company', self.ctx, main_window=self)
@ -284,9 +275,7 @@ class FrontWindow(QMainWindow):
if self._commission_activated: if self._commission_activated:
self.Agent = Model('commission.agent', self.ctx, main_window=self) self.Agent = Model('commission.agent', self.ctx, main_window=self)
self.Comission = Model('commission', self.ctx, main_window=self) self.Comission = Model('commission', self.ctx, main_window=self)
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)
self.device, = self.Device.find([ self.device, = self.Device.find([
('id', '=', self._user['sale_device']), ('id', '=', self._user['sale_device']),
]) ])
@ -297,19 +286,20 @@ class FrontWindow(QMainWindow):
self._journals = self.device['journals.'] self._journals = self.device['journals.']
self.salesman_ids = [s['id'] for s in self.shop.get('salesmans', [])] self.salesman_ids = [s['id'] for s in self.shop.get('salesmans', [])]
dom_salesman = [ # dom_salesman = [
('company', '=', self.company), # ('company', '=', self.company),
] # ]
if self.salesman_ids: # if self.salesman_ids:
dom_salesman.append(('id', 'in', self.salesman_ids)) # dom_salesman.append(('id', 'in', self.salesman_ids))
self.discounts = self.Discount.find([ # self.discounts = self.Discount.find([
('type_discount', '=', 'percentage') # ('type_discount', '=', 'percentage')
]) # ])
self.discounts_fixed = self.Discount.find([]) self.discounts_fixed = self.Discount.find([])
self.discounts = [dsc for dsc in self.discounts_fixed if dsc['type_discount'] == 'percentage']
self.delivery_man_table = self.shop.get('delivery_man.', []) self.delivery_man_table = self.shop.get('delivery_man.', [])
if self.delivery_man_table: if self.delivery_man_table:
self.delivery_man = [d for d in self.delivery_man_table if d['active']] self.delivery_man_table = [d for d in self.delivery_man_table if d['active']]
self._payment_terms = self.PaymentTerm.find([ self._payment_terms = self.PaymentTerm.find([
('active', '=', True) ('active', '=', True)
], order=[('name', 'ASC')]) ], order=[('name', 'ASC')])
@ -334,6 +324,17 @@ class FrontWindow(QMainWindow):
self.default_payment_term = self.shop['payment_term.'] self.default_payment_term = self.shop['payment_term.']
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':
self._sale_pos_restaurant = self.Module.find([
('name', '=', 'sale_pos_frontend_rest'),
('state', '=', 'activated'),
])
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 = self.Sale.get_product_printers(
self.shop['id'])
self._action_report_invoice, = self.ActionReport.find([ self._action_report_invoice, = self.ActionReport.find([
('report_name', '=', 'account.invoice'), ('report_name', '=', 'account.invoice'),

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -26,7 +26,7 @@ MODELS_RESTAURANT = {
'sale.sale': { 'sale.sale': {
'rec_name': 'number', 'rec_name': 'number',
'fields': [ 'fields': [
'number', 'party.rec_name', 'lines', 'sale_date', 'state', 'number', 'party.name', 'lines', 'sale_date', 'state',
'total_amount_cache', 'salesman.rec_name', 'total_amount_cache', 'salesman.rec_name',
'payment_term.rec_name', 'payments', 'tip_amount', 'payment_term.rec_name', 'payments', 'tip_amount',
'total_amount', 'residual_amount', 'paid_amount', 'untaxed_amount', 'total_amount', 'residual_amount', 'paid_amount', 'untaxed_amount',
@ -63,7 +63,7 @@ MODELS_RESTAURANT = {
'rec_name': 'rec_name', 'rec_name': 'rec_name',
'fields': [ 'fields': [
# 'active', # 'active',
'party.id_number', 'party.rec_name', 'rec_name', 'plan.percentage' 'party.id_number', 'party.name', 'rec_name', 'plan.percentage'
] ]
}, },
'sale.delivery_party': { 'sale.delivery_party': {
@ -247,12 +247,12 @@ MODELS_RETAIL = {
'sale.sale': { 'sale.sale': {
'rec_name': 'number', 'rec_name': 'number',
'fields': [ 'fields': [
'number', 'party.rec_name', 'lines', 'sale_date', 'state', 'number', 'party.name', 'lines', 'sale_date', 'state',
'total_amount_cache', 'salesman.rec_name', 'total_amount_cache', 'salesman.rec_name',
'payment_term.rec_name', 'payments', 'tip_amount', 'payment_term.rec_name', 'payments', 'tip_amount',
'total_amount', 'residual_amount', 'paid_amount', 'untaxed_amount', 'total_amount', 'residual_amount', 'paid_amount', 'untaxed_amount',
'tax_amount', 'delivery_charge', 'price_list', 'invoice_number', 'tax_amount', 'delivery_charge', 'price_list', 'invoice_number',
'shipment_address', 'kind', 'shop', 'shipment_address', 'kind', 'shop', 'turn',
'delivery_party', 'reference', 'comment', 'payment_method', 'delivery_party', 'reference', 'comment', 'payment_method',
'delivery_state', 'invoice_type', 'net_amount', 'delivery_state', 'invoice_type', 'net_amount',
'delivery_amount', 'source.rec_name', 'position', 'delivery_amount', 'source.rec_name', 'position',
@ -282,7 +282,7 @@ MODELS_RETAIL = {
'rec_name': 'rec_name', 'rec_name': 'rec_name',
'fields': [ 'fields': [
# 'active', # 'active',
'party.id_number', 'party.rec_name', 'rec_name', 'plan.percentage' 'party.id_number', 'party.name', 'rec_name', 'plan.percentage'
] ]
}, },
'sale.delivery_party': { 'sale.delivery_party': {

View File

@ -80,8 +80,8 @@ class Model(object):
self.conn = HTTPSConnection self.conn = HTTPSConnection
self.context_http = context_http self.context_http = context_http
enviroment = ctx['params']['enviroment'] environment = ctx['params']['environment']
if enviroment == 'retail': if environment == 'retail':
_model = MODELS_RETAIL.get(model) _model = MODELS_RETAIL.get(model)
else: else:
_model = MODELS_RESTAURANT.get(model) _model = MODELS_RESTAURANT.get(model)
@ -123,6 +123,7 @@ class Model(object):
res = self.get_connection('POST', '/fields_get', args_) res = self.get_connection('POST', '/fields_get', args_)
return res return res
# deprecated
def write_many(self, ids, values, fields=None): def write_many(self, ids, values, fields=None):
if not fields: if not fields:
fields = self.fields fields = self.fields
@ -162,6 +163,15 @@ class Model(object):
res = self.get_connection('POST', '/create', args_) res = self.get_connection('POST', '/create', args_)
return res return res
def search_count(self, domain):
args_ = {
'model': self.model,
'domain': domain,
'context': self.ctx,
}
res = self.get_connection('POST', '/search_count', args_)
return res
def method_instance(self, method, instance): def method_instance(self, method, instance):
args_ = { args_ = {
'model': self.model, 'model': self.model,

View File

@ -63,7 +63,7 @@ SSH_PORT = 23
def money(value): def money(value):
if type(value) is int: if type(value) is int:
value = int(value) value = int(value)
return '{:,}'.format(value) return '{:,.2f}'.format(value)
dev_printers = {} dev_printers = {}
@ -95,9 +95,9 @@ class Receipt(object):
self._print_invoice_payment = context.get('print_invoice_payment') self._print_invoice_payment = context.get('print_invoice_payment')
self._delta_locale = context.get('delta_locale') self._delta_locale = context.get('delta_locale')
self._environment = environment self._environment = environment
self.order_copies = context.get('order_copies') self.order_copies = context.get('order_copies') or 0
self.invoice_copies = context.get('invoice_copies') self.invoice_copies = context.get('invoice_copies') or 0
self.order_kind = 'dispatch' if environment == 'restaurant' else 'command' self.order_kind = 'command' if environment == 'restaurant' else 'dispatch'
self._row_characters = _ROW_CHARACTERS self._row_characters = _ROW_CHARACTERS
if context.get('row_characters'): if context.get('row_characters'):
@ -830,10 +830,10 @@ class Receipt(object):
self._printer.cashdraw(2) self._printer.cashdraw(2)
self.print_enter() self.print_enter()
def print_orders(self, orders, reversion=None, kind='command'): def print_orders(self, orders, reversion=None):
res = [] res = []
self.order_kind = kind kind = self.order_kind
for order in orders.values(): for order in orders:
try: try:
self._printer = None self._printer = None
if dev_printers.get(order['host']) and kind != 'command': if dev_printers.get(order['host']) and kind != 'command':
@ -906,6 +906,7 @@ class Receipt(object):
self._printer.text('TURNO: %s' % str(turn)) self._printer.text('TURNO: %s' % str(turn))
self._printer.ln(2) self._printer.ln(2)
kind = order.get('kind', None) kind = order.get('kind', None)
_kind = ''
if self._environment != 'retail' and kind: if self._environment != 'retail' and kind:
if kind == 'take_away': if kind == 'take_away':
_kind = 'PARA LLEVAR' _kind = 'PARA LLEVAR'

20
app/stats.py Normal file
View File

@ -0,0 +1,20 @@
import cProfile
import pstats
# wrapper
def profile_filter(func):
def profiled_func(*args, **kwargs):
profiler = cProfile.Profile()
profiler.enable()
result = profiler.runcall(func, *args, **kwargs)
# Captura las estadísticas
stats = pstats.Stats(profiler)
profiler.disable()
stats.sort_stats('cumulative')
# Imprime las estadísticas en la salida estándar
stats.print_stats()
return result
return profiled_func

View File

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

View File

@ -1,15 +0,0 @@
Tryton POS Client (Using Qt5 and Python3)
=========================================
# FOR WINDOWS
Download and install python-3.7.9-amd64
> pip install PyQt5==5.8.1.1
Copy config_pos.ini on user AppData/Local/tryton
Modify config_pos.ini
Put launcher on desktop and set icon change
name "pospro.pyw"

View File

@ -1,15 +0,0 @@
# Three steps for translating Qt App
From main directory:
1. Clean obsolete translations:
pylupdate5 -noobsolete project.pro
2. Do translate .ts file, opening linguist tool:
/usr/bin/linguist
3. Release translation
lrelease app/locale/i18n_es.ts

4
pospro
View File

@ -25,6 +25,10 @@ class Client(object):
def __init__(self, parent=None): def __init__(self, parent=None):
self.app = QApplication(sys.argv) self.app = QApplication(sys.argv)
self.app.setOrganizationName("PRESIK SAS")
self.app.setOrganizationDomain("presik.com")
self.app.setApplicationName("SMART POS")
self.app.setStyle("Fusion")
def init_login(self): def init_login(self):
_file_config = 'config_pos.ini' _file_config = 'config_pos.ini'

View File

@ -60,7 +60,7 @@ setup(
'Operating System :: OS Independent', 'Operating System :: OS Independent',
'Natural Language :: English', 'Natural Language :: English',
'Natural Language :: Spanish', 'Natural Language :: Spanish',
'Programming Language :: Python', 'Programming Language :: Python3.10',
'Topic :: Office/Business', 'Topic :: Office/Business',
], ],
license='GPL', license='GPL',

View File

@ -1,6 +1,8 @@
#!/usr/bin/env python3 #!/usr/bin/env python3
from app.reporting import Receipt from app.reporting import Receipt
import traceback
import time
if __name__ == '__main__': if __name__ == '__main__':
@ -69,6 +71,10 @@ if __name__ == '__main__':
receipt = Receipt(ctx_printing) receipt = Receipt(ctx_printing)
# try: # try:
receipt.config_printer(printer_test) receipt.config_printer(printer_test)
for i in range(20):
receipt.test_printer() receipt.test_printer()
time.sleep(1)
# receipt._printer.close()
# print('impresion numero', i)
# except : # except :
# print('Printing failed...!') # print('Printing failed...!')

View File

@ -53,5 +53,5 @@ fake_data = {
} }
receipt = Receipt(context={}, environment='restaurant') receipt = Receipt(context={}, environment='restaurant')
for i in range(12): for i in range(20):
receipt.print_tasks(fake_data) receipt.print_tasks(fake_data)