presik_pos/app/frontwindow.py

398 lines
16 KiB
Python

import os
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
from .proxy import Model
from .constants import SCREENS
from .dialogs import (
Help, ControlPanel, SearchSale, SearchParty, SearchProduct, Position,
Comment, DialogPayment, DialogVoucher, DialogPrintInvoice, ProductEdit,
DialogGlobalDiscount, DialogPaymentTerm, DialogStock, DialogOrder,
DialogForceAssign, DialogTaxes, DialogCancelInvoice, DialogAgent,
DialogConsumer, DialogManageTables, DialogMoneyCount, CombineProduct,
DialogAuthDiscounts, DeliveryPartySelected, DialogTableDeliveryParty,
DialogHistoricSales, DialogSaleForm, DialogSource, DialogReports,
DialogDeliveryParty, TipAmount, DeliveryAmount, DialogSalesmanCode,
DialogFixedDiscounts, DialogFixedDiscountsManual, DialogComboProduct,
DialogSplitSale, DialogExpenses, DialogInfoProduct, DialogAdvance,
DialogDeleteProduct, DialogCollection
)
from .constants import DIALOG_REPLY_YES
from .version import __version__
__all__ = ['FrontWindow', 'ClearUi']
parent = Path(__file__).parent
file_base_css = os.path.join(str(parent), 'css', 'base.css')
_DEFAULT_TIMEOUT = 60000 # on ms (100 minutes)
class FrontWindow(QMainWindow):
def __init__(self, context, params, title=None, show_mode=None):
super(FrontWindow, self).__init__()
if not title:
title = 'APLICACION'
self._state = None
self._keyStates = {}
self.window().setWindowTitle(title)
self.setObjectName('WinMain')
# self.conn = connection
self.version = __version__
self.set_params(params)
self.logger = logging.getLogger('app_logger')
"""
We need get the size of screen (display)
--------------- -------------------
name width (px)
--------------- -------------------
small screen =< 1024
medium screen > 1024 and =< 1366
large screen > 1366
"""
screen = QGuiApplication.primaryScreen().size()
# screen = QDesktopWidget().screenGeometry()
self.setGeometry(0, 0, screen.width(), screen.height())
self.screen_width = screen.width()
self.screen_height = screen.height()
self.screen_size = 'large'
if self.screen_width <= 1024:
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()
self.global_timer = 0
_theme = params['theme'] if params.get('theme') else None
self.profile_printer = params['profile_printer'] if params.get('profile_printer') else 'TM-P80'
self.set_style(SCREENS[self.screen_size], _theme)
self.label_color = 'gray'
self.label_color_2 = ''
if _theme == 'dark':
self.label_color = 'light'
self.label_color_2 = 'orange'
self.window().showMaximized()
def filter_cache(self, data, filter, target):
res = []
for d in data:
for t in target:
if t in d[filter]:
res.append(d)
return res
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):
styles = []
if theme_css:
theme_css = os.path.join(str(parent), 'css', theme_css + '.css')
for style in [theme_css or file_base_css, file_css]:
with open(style, 'r') as infile:
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):
dialog = self.dialog('confirm_exit', response=True)
response = dialog.exec_()
if response == DIALOG_REPLY_YES:
self.check_empty_sale()
if self.active_weighing and self.reader_thread:
self.reader_thread.onClose()
super(FrontWindow, self).close()
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):
for k, v in values.items():
if v in ('False', 'True'):
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
def create_dialogs(self):
self.dialog_control_panel = ControlPanel(self)
self.dialog_money_count = DialogMoneyCount(self)
self.dialog_search_sales = SearchSale(self)
self.dialog_search_parties = SearchParty(self)
self.dialog_search_products = SearchProduct(self)
self.dialog_position = Position(self)
self.dialog_tip_amount = TipAmount(self)
self.dialog_delivery_amount = DeliveryAmount(self)
self.dialog_comment = Comment(self)
self.dialog_payment = DialogPayment(self)
self.dialog_voucher = DialogVoucher(self)
self.dialog_delete_product = DialogDeleteProduct(self)
self.dialog_advance = DialogAdvance(self)
self.dialog_print_invoice = DialogPrintInvoice(self)
self.dialog_global_discount = DialogGlobalDiscount(self)
self.dialog_auth_discount = DialogAuthDiscounts(self)
self.dialog_fixed_discount = DialogFixedDiscounts(self)
self.dialog_fixed_discount_manual = DialogFixedDiscountsManual(self)
self.dialog_payment_term = DialogPaymentTerm(self)
self.dialog_search_sales.activate_counter()
self.dialog_product_stock = DialogStock(self.dialog_search_products)
self.dialog_order = DialogOrder(self)
self.dialog_force_assign = DialogForceAssign(self)
self.field_password_force_assign_ask.setEchoMode(QLineEdit.Password)
self.dialog_tax = DialogTaxes(self)
self.dialog_cancel_invoice = DialogCancelInvoice(self)
self.dialog_product_edit = ProductEdit(self)
self.dialog_table_delivery_party = DialogTableDeliveryParty(self)
self.dialog_delivery_party_selected = DeliveryPartySelected(self)
self.dialog_delivery_party = DialogDeliveryParty(self)
self.dialog_salesman_code = DialogSalesmanCode(self)
self.dialog_reports = DialogReports(self)
self.dialog_source = DialogSource(self)
self.dialog_split_sale = DialogSplitSale(self)
self.dialog_expenses = DialogExpenses(self)
self.dialog_info_product = DialogInfoProduct(self)
if self._commission_activated:
self.dialog_agent = DialogAgent(self)
if self.enviroment == 'restaurant' and self._sale_pos_restaurant:
self.dialog_combine_product = CombineProduct(self)
self.dialog_combo_product = DialogComboProduct(self)
self.dialog_historic_sales = DialogHistoricSales(self)
self.dialog_sale_form = DialogSaleForm(self)
self.dialog_consumer = DialogConsumer(self)
self.dialog_manage_tables = DialogManageTables(self)
else:
self.dialog_collection = DialogCollection(self)
def action_help(self):
Help(self).show()
def resize_window_tablet_dev(self):
self.resize(690, self.get_geometry()[1])
def get_allow_categories_ids(self):
allow_cat = []
allow_cat_append = allow_cat.append
allow_cat_extend = allow_cat.extend
for pc in self.product_categories:
allow_cat_append(pc['id'])
allow_cat_extend(pc['childs'])
return allow_cat
def load_modules(self):
self._sale_pos_restaurant = None
time1 = time.time()
self.Module = Model('ir.module', self.ctx)
print(time.time() - time1, 'final')
self.Config = Model('sale.configuration', self.ctx)
self._config, = self.Config.find([('id', '=', 1)])
self.discount_method = self._config.get('discount_pos_method')
self.allow_discount_handle = self._config.get('allow_discount_handle', None)
self.sale_automatic = False
if self.enviroment == 'retail' and self._config.get('new_sale_automatic'):
self.sale_automatic = True
self._commission_activated = self.Module.find([
('name', '=', 'commission'),
('state', '=', 'activated'),
])
# self._source = self.Module.find([
# ('name', '=', 'sale_source'),
# ('state', '=', 'activated'),
# ])
self._credit_limit_activated = self.Module.find([
('name', '=', 'account_credit_limit'),
('state', '=', 'activated'),
])
_product = {
'name': 'product.product',
'fields': [
'template.name', 'code', 'write_date',
'description', 'template.sale_price_w_tax',
'template.account_category'
]
}
self.cache_local = self._config.get('cache_products_local')
if self._config['show_location_pos']:
_product['fields'].append('location_')
if self._config['show_stock_pos'] in ('value', 'icon'):
if self._config['show_stock_pos'] == 'value':
_product['fields'].append('quantity')
if self._config['show_brand']:
_product['fields'].append('brand.name')
if self._config['encoded_sale_price']:
_product['fields'].extend(
['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)
self._user, = self.User.find([('login', '=', self.user)])
self.Company = Model('company.company', self.ctx)
self._company, = self.Company.find([('id', '=', 1)])
self.logo = self._company['logo']
sale_device = self._user['sale_device']
if not sale_device:
return 'user_not_permissions_device'
self.ctx['user'] = self._user['id']
self.ctx['sale_device'] = sale_device
self.ctx['shop'] = self._user['shop']
self.Sale = Model('sale.sale', self.ctx)
self.SaleLine = Model('sale.line', self.ctx)
self.Product = Model('product.product', self.ctx)
self.Journal = Model('account.statement.journal', self.ctx)
self.Statement = Model('account.statement', self.ctx)
self.Expenses = Model('sale_pos.expenses_daily', self.ctx)
self.Employee = Model('company.employee', self.ctx)
self.Shop = Model('sale.delivery_party', self.ctx)
self.SaleDiscont = Model('sale.discount', self.ctx)
self.Device = Model('sale.device', self.ctx)
self.Category = Model('product.category', self.ctx)
self.PaymentTerm = Model('account.invoice.payment_term', self.ctx)
self.Party = Model('party.party', self.ctx)
self.DeliveryParty = Model('sale.delivery_party', self.ctx)
self.Taxes = Model('account.tax', self.ctx)
self.Discount = Model('sale.discount', self.ctx, fields=[
'name', 'active', 'discount', 'type_discount'
])
self.ActionReport = Model('ir.action.report', self.ctx)
if self._commission_activated:
self.Agent = Model('commission.agent', self.ctx)
self.Comission = Model('commission', self.ctx)
if self._sale_pos_restaurant:
self.RestTables = Model('sale.shop.table', self.ctx)
self.Consumer = Model('party.consumer', self.ctx)
self.device, = self.Device.find([
('id', '=', self._user['sale_device']),
])
self.shop = self.device['shop.']
self.shop_taxes = self.shop['taxes.']
self.company = self.shop['company']
self._journals = self.device['journals.']
self.salesman_ids = [s['id'] for s in self.shop.get('salesmans', [])]
dom_salesman = [
('company', '=', self.company),
]
if self.salesman_ids:
dom_salesman.append(('id', 'in', self.salesman_ids))
self.discounts = self.Discount.find([
('type_discount', '=', 'percentage')
])
self.discounts_fixed = self.Discount.find([])
self.delivery_man_table = self.shop.get('delivery_man.', [])
if self.delivery_man_table:
self.delivery_man = [d for d in self.delivery_man_table if d['active']]
self._payment_terms = self.PaymentTerm.find([
('active', '=', True)
], order=[('name', 'ASC')])
self.type_pos_user = self._user.get('type_pos_user')
if not self.type_pos_user:
return 'user_without_permission'
self.user_can_delete = self.type_pos_user in ('frontend_admin', 'cashier')
self.product_categories = self.shop['product_categories.']
self.allow_categories_ids = self.get_allow_categories_ids()
self.salesman_required = self.shop['salesman_pos_required']
self.default_party = self.shop['party.']
if not self.default_party:
return 'missing_party_configuration'
self.default_journal = self.device['journal.']
if not self.default_journal:
return 'missing_journal_device'
self.default_payment_term = self.shop['payment_term.']
self._password_admin = self._config.get('password_admin_pos')
self._password_force_assign = self._config.get('password_force_assign')
self._action_report, = self.ActionReport.find([
('report_name', '=', 'account.invoice'),
])
if self._config['show_stock_pos'] in ('value', 'icon'):
self.stock_context = {
'stock_date_end': date.today(),
'locations': [self.shop['warehouse']],
}
self.Source = Model('sale.source', self.ctx)
self.Pricelist = Model('product.price_list', self.ctx)
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()