Refactory models

This commit is contained in:
Oscar Alvarez 2020-12-20 06:14:56 -05:00
parent fb18340668
commit 1ae1f76f22
8 changed files with 386 additions and 171 deletions

10
INSTALL
View File

@ -16,15 +16,19 @@ Prerequisites Client
* python3-pil
* Required, Pip packages:
pip3 install pyusb
pip3 install pillow
pip3 install qrcode
pip3 install paramiko
pip3 install pycups
pip3 install requests
pip3 install simplejson
pip3 install requests
pip3 install simplejson
pip3 install escpos
For Windows add:
pip3 install PyQt5==5.8.0
pip3 install win32printing
pip3 install escpos
Prerequisites Server Modules

View File

@ -1,7 +1,7 @@
Instalación de Tryton POS Client Qt5
====================================
Esta versión solo es compatible con Tryton 4.0+, se asume que el usuario tiene
Esta versión solo es compatible con Tryton 5.0+, se asume que el usuario tiene
conocimientos básicos previos sobre la instalación y configuración de Tryton,
especialmente los modulos oficiales relacionados con contabilidad y ventas, no
es el objeto de esta guia abordar temas de configuración básica.
@ -29,15 +29,20 @@ En Debian, Ubuntu y Derivados, se recomienda usar: $ apt install paquete
Los siguientes paquetes se deben instalar usando PIP
pip3 install pyusb
pip3 install pillow
pip3 install qrcode
pip3 install paramiko
pip3 install pycups
pip3 install requests
pip3 install simplejson
pip3 install win32printing
pip3 install escpos
pip3 install pyusb
pip3 install pillow
pip3 install qrcode
pip3 install paramiko
pip3 install pycups
pip3 install requests
pip3 install simplejson
pip3 install escpos
Para Windows agregar:
pip install pywin32
pip install PyQt5==5.8.0
pip install win32printing
Tener en cuenta que algunos paquetes se deben instalar con pip para python3.

View File

@ -31,7 +31,7 @@ class ButtonsFunction(QGridLayout):
self.parent = parent
self.set_values(values)
if self.parent.enviroment == 'restaurant':
rows = 3
rows = 4
columns = 4
name_style = 'toolbar'
@ -161,7 +161,7 @@ class ButtonsStacked(QHBoxLayout):
# method='button_plus_pressed',
# name_style='toolbar',
# )
#self.addWidget(self.button_plus, 0)
# self.addWidget(self.button_plus, 0)
if parent.type_pos_user == 'order' or parent.type_pos_user == 'salesman':
self.button_send_order = CustomButton(

View File

@ -2,10 +2,11 @@
from operator import itemgetter
from .commons.dialogs import HelpDialog, QuickDialog
from PyQt5.QtCore import QRect, Qt
from PyQt5.QtWidgets import (QWidget, QLabel, QTextEdit, QVBoxLayout,
QGridLayout, QLineEdit, QScrollArea, QHBoxLayout,
QDoubleSpinBox, QDateEdit, QDesktopWidget,
QPlainTextEdit, QCheckBox)
from PyQt5.QtWidgets import (
QWidget, QLabel, QTextEdit, QVBoxLayout, QGridLayout, QLineEdit,
QScrollArea, QHBoxLayout, QDoubleSpinBox, QDateEdit, QDesktopWidget,
QPlainTextEdit, QCheckBox
)
from .constants import (alignCenter, alignLeft, FRACTIONS)
from .commons.forms import FieldMoney, ComboBox
from .commons.search_window import SearchWindow
@ -16,6 +17,18 @@ from app.commons.table import TableView
from .commons.custom_button import CustomButton
from .tools import get_icon
__all__ = [
'ControlPanel', 'SearchSale', 'SearchParty', 'SearchProduct', 'SaleLine',
'Comment', 'Position', 'DialogPayment', 'DialogTaxes', 'DialogChannel',
'DialogTableMoneyCount', 'DialogTableDeliveryParty', 'DialogDeliveryMen',
'Help', 'DeliveryPartySelected', 'DialogPrintInvoice', 'DialogStock',
'DialogGlobalDiscountTable', 'DialogSalesman', 'DialogAgent',
'DialogOrder', 'DialogGlobalDiscount', 'DialogVoucher', 'DialogConsumer',
'DialogManageTables', 'DialogTableSaleConsumer', 'SaleConsumerSelected',
'DialogCancelInvoice', 'DialogForceAssign'
]
TYPE_VEHICLE = [
('', ''),
('motorcycle', 'Motorcycle'),
@ -24,6 +37,13 @@ TYPE_VEHICLE = [
]
def get_screen():
screen = QDesktopWidget().screenGeometry()
width = screen.width()
height = screen.height()
return width, height
def create_vbox(parent, values, method, columns=4, dimension=None):
vbox_ = QVBoxLayout()
grid = QGridLayout()
@ -36,10 +56,10 @@ def create_vbox(parent, values, method, columns=4, dimension=None):
scroll_area.setWidgetResizable(True)
scroll_area.setVerticalScrollBarPolicy(Qt.ScrollBarAlwaysOn)
scroll_area.setWidget(grid_buttons)
width, height = get_screen()
if dimension:
screen = QDesktopWidget().screenGeometry()
width = screen.width() / dimension[0]
height = screen.height() / dimension[0]
width = width / dimension[0]
height = height / dimension[0]
scroll_area.setFixedSize(width, height)
grid.addWidget(scroll_area)
vbox_.addLayout(grid)
@ -54,7 +74,6 @@ class ControlPanel(QWidget):
def get(self, menu_dash):
string_ = self.tr('CONTROL PANEL')
screen = QDesktopWidget().screenGeometry()
vbox_ = QVBoxLayout()
grid = QGridLayout()
scroll_area = QScrollArea()
@ -62,7 +81,8 @@ class ControlPanel(QWidget):
grid.addWidget(scroll_area)
vbox_.addLayout(grid)
dialog = QuickDialog(self._parent, 'action', widgets=[vbox_])
dialog.setFixedSize(screen.width()/2, screen.height()/1.2)
width, height = get_screen()
dialog.setFixedSize(width/2, height/1.2)
dialog.setWindowTitle(string_)
return dialog
@ -90,8 +110,8 @@ class SearchSale(QWidget):
'on_return_method': 'on_selected_sale'
}
return SearchWindow(self._parent, headers, None, methods,
filter_column=[1, 2, 3, 4], cols_width=widths,
title=title, fill=True)
filter_column=[1, 2, 3, 4], cols_width=widths,
title=title, fill=True)
class SearchParty(QWidget):
@ -190,15 +210,15 @@ class DialogManageTables(QWidget):
self._parent = parent
def get(self):
if not self._parent._Tables:
if not self._parent._sale_pos_restaurant:
return
tables = self._parent._Tables.find([
tables = self._parent.RestTables.find([
('shop', '=', self._parent.shop['id'])
])
_tables = ManageTables(self._parent, tables, self._parent.action_table_assigned)
dialog = QuickDialog(self._parent, 'action', widgets=[_tables])
screen = QDesktopWidget().screenGeometry()
dialog.setFixedSize(screen.width()/1.5, screen.height()/1.5)
width, height = get_screen()
dialog.setFixedSize(width/1.5, height/1.5)
return dialog
@ -212,7 +232,6 @@ class DialogConsumer(QWidget):
self._parent._consumer = None
vbox_consumer = QVBoxLayout()
grid = QGridLayout()
screen = QDesktopWidget().screenGeometry()
label_phone = QLabel(self.tr('PHONE:'))
label_phone.setObjectName('label_phone')
@ -278,7 +297,8 @@ class DialogConsumer(QWidget):
vbox_consumer.addLayout(grid)
dialog = QuickDialog(self._parent, 'action', widgets=[vbox_consumer])
dialog.setWindowTitle('CONSUMER')
dialog.setGeometry(0, 0, screen.width()/2.7, screen.height()/1.8)
width, height = get_screen()
dialog.setGeometry(0, 0, width/2.7, height/1.8)
dialog.accepted.connect(self._parent.dialog_search_consumer_accepted)
return dialog
@ -302,14 +322,16 @@ class DialogTableSaleConsumer(QWidget):
def get(self):
string_ = self.tr('SALES')
col_sizes_tlines = [field['width'] for field in self._parent.fields_sale_consumer]
width, height = get_screen()
col_sizes_tlines = [
field['width'] for field in self._parent.fields_sale_consumer
]
table = TableView('model_sale_consumer',
self._parent.model_sale_consumer, col_sizes_tlines,
method_selected_row=self._parent.sale_consumer_selected)
self._parent.model_sale_consumer, col_sizes_tlines,
method_selected_row=self._parent.sale_consumer_selected
)
screen = QDesktopWidget().screenGeometry()
table.setFixedSize(screen.width()/1.5, screen.height()/2)
table.setFixedSize(width/1.5, height/2)
vbox_ = QVBoxLayout()
layout = QVBoxLayout()
@ -319,7 +341,7 @@ class DialogTableSaleConsumer(QWidget):
vbox_.addLayout(layout)
vbox_.addSpacing(10)
dialog = QuickDialog(self._parent, 'action', widgets=[vbox_])
dialog.setFixedSize(screen.width()/1.3, screen.height()/1.7)
dialog.setFixedSize(width/1.3, height/1.7)
dialog.setWindowTitle(string_)
return dialog
@ -332,7 +354,6 @@ class SaleConsumerSelected(QWidget):
def get(self):
vbox_ = QVBoxLayout()
grid = QGridLayout()
screen = QDesktopWidget().screenGeometry()
label_party = QLabel(self.tr('PARTY:'))
label_party.setAlignment(alignLeft)
@ -371,8 +392,9 @@ class SaleConsumerSelected(QWidget):
label_lines.setObjectName('label_lines')
grid.addWidget(label_lines, 3, 1, 1, 4)
col_sizes_tlines = [field['width'] for field in self._parent.fields_sale_line]
table = TableView('model_sale_lines', self._parent.model_sale_customer_lines,
col_sizes_tlines)
table = TableView('model_sale_lines',
self._parent.model_sale_customer_lines, col_sizes_tlines
)
grid.addWidget(table, 4, 1, 1, 4)
label_untaxed = QLabel(self.tr('UNTAXED AMOUNT:'))
@ -404,7 +426,8 @@ class SaleConsumerSelected(QWidget):
vbox_.addLayout(grid)
dialog = QuickDialog(self._parent, 'action', widgets=[vbox_])
dialog.setFixedSize(screen.width()/1.2, screen.height()/1.2)
width, height = get_screen()
dialog.setFixedSize(width/1.2, height/1.2)
return dialog
def get_button(self):
@ -554,7 +577,6 @@ class DialogSalesman(QWidget):
newlist = sorted(self._parent.employees, key=itemgetter('rec_name'))
employees_ = [[e['id'], '', e['rec_name'], ' ']
for e in newlist]
screen = QDesktopWidget().screenGeometry()
vbox_salesman = create_vbox(
self._parent, employees_, self._parent.on_selected_salesman,
@ -563,7 +585,8 @@ class DialogSalesman(QWidget):
dialog = QuickDialog(self._parent, 'action', size=(800, 500), widgets=[vbox_salesman])
dialog.setWindowTitle(string_)
dialog.setFixedSize(screen.width()/1.5, screen.height()/1.5)
width, height = get_screen()
dialog.setFixedSize(width/1.5, height/1.5)
return dialog
@ -595,14 +618,13 @@ class DialogDeliveryMen(QWidget):
newlist = sorted(self._parent.delivery_man, key=itemgetter('rec_name'))
man_ = [[e['id'], '', e['rec_name'], e['number_plate'] or ' ']
for e in newlist]
screen = QDesktopWidget().screenGeometry()
vbox_salesman = create_vbox(self._parent, man_,
self._parent.on_selected_delivery_men,
dimension=[1.7, 1.8])
self._parent.on_selected_delivery_men, dimension=[1.7, 1.8])
dialog = QuickDialog(self._parent, 'action', size=(800, 500),
widgets=[vbox_salesman])
dialog.setWindowTitle(string_)
dialog.setFixedSize(screen.width()/1.5, screen.height()/1.5)
width, height = get_screen()
dialog.setFixedSize(width/1.5, height/1.5)
return dialog
@ -693,11 +715,11 @@ class DialogTableDeliveryParty(QWidget):
col_sizes_tlines = [field['width'] for field in self._parent.fields_delivery_party]
table = TableView('model_delivery_party',
self._parent.model_delivery_party, col_sizes_tlines,
method_selected_row=self._parent.delivery_party_selected)
screen = QDesktopWidget().screenGeometry()
table.setFixedSize(screen.width()/2.2, screen.height()/2.2)
self._parent.model_delivery_party, col_sizes_tlines,
method_selected_row=self._parent.delivery_party_selected
)
width, height = get_screen()
table.setFixedSize(width/2.2, height/2.2)
vbox_ = QVBoxLayout()
grid = QGridLayout()
@ -708,7 +730,8 @@ class DialogTableDeliveryParty(QWidget):
vbox_.addLayout(grid)
dialog = QuickDialog(self._parent, 'action', widgets=[vbox_])
dialog.setGeometry(0, 0, screen.width()/1.8, screen.height()/1.5)
width, height = get_screen()
dialog.setGeometry(0, 0, width/1.8, height/1.5)
dialog.setWindowTitle(string_)
return dialog
@ -736,8 +759,8 @@ class DialogTableMoneyCount(QWidget):
table = TableView('model_money_count', self._parent.model_money_count,
col_sizes_tlines, selection_edit=True)
screen = QDesktopWidget().screenGeometry()
table.setFixedSize(screen.width()/3.3, screen.height()/3)
width, height = get_screen()
table.setFixedSize(width/3.3, height/3)
vbox_ = QVBoxLayout()
label, field = self.get_fields()
@ -756,7 +779,8 @@ class DialogTableMoneyCount(QWidget):
vbox_.addLayout(layout2)
vbox_.addSpacing(20)
dialog = QuickDialog(self._parent, 'action', widgets=[vbox_])
dialog.setGeometry(0, 0, screen.width()/3, screen.height()/1.8)
width, height = get_screen()
dialog.setGeometry(0, 0, width/3, height/1.8)
dialog.setWindowTitle(string_)
dialog.accepted.connect(self._parent.dialog_money_count_accepted)
return dialog
@ -773,6 +797,7 @@ class DialogTableMoneyCount(QWidget):
self._parent.row_field_total_money.setAlignment(alignLeft)
return label_amount, self._parent.row_field_total_money
class DialogTaxes(QWidget):
def __init__(self, parent):
super(DialogTaxes, self).__init__(parent)
@ -799,14 +824,17 @@ class DialogChannel(QWidget):
def get(self):
string_ = self.tr('SELECT CHANNEL')
channels = [[c['id'], '', c['rec_name'].upper(), str(c['id'])]
for c in self._parent.channels]
channels = [
[c['id'], '', c['rec_name'].upper(), str(c['id'])]
for c in self._parent.channels
]
vbox_ = create_vbox(self._parent, channels,
self._parent.on_selected_channel)
dialog = QuickDialog(self._parent, 'action', widgets=[vbox_])
dialog.setWindowTitle(string_)
return dialog
class DialogPaymentTerm(QWidget):
def __init__(self, parent):
super(DialogPaymentTerm, self).__init__(parent)

View File

@ -26,7 +26,7 @@ from app.commons.forms import GridForm, ComboBox, FieldNumeric
from app.commons.messages import MessageBar
from app.commons.image import Image
from app.commons.table import TableView
from app.commons.model import TableModel, Modules, TableModelEdit
from app.commons.model import TableModel, TableModelEdit
from app.commons.frontwindow import FrontWindow
from app.commons.menu_buttons import MenuDash
from .proxy import FastModel
@ -173,7 +173,7 @@ class MainWindow(FrontWindow):
def get_current_sale(self):
if hasattr(self, '_sale') and self._sale['id']:
sales = self.ModSale.find([
sales = self.Sale.find([
('id', '=', self._sale['id'])
])
if not sales:
@ -197,7 +197,7 @@ class MainWindow(FrontWindow):
def delete_current_sale(self):
if self._sale['id']:
self.ModSale.cancel_sale(self._sale['id'])
self.Sale.cancel_sale(self._sale['id'])
def resize_window_tablet_dev(self):
self.resize(690, self.get_geometry()[1])
@ -250,7 +250,7 @@ class MainWindow(FrontWindow):
})
def load_modules(self):
modules = Modules(self, self.conn)
# modules = Modules(self, self.conn)
self._sale_pos_restaurant = None
self.Module = FastModel('ir.module', self.ctx)
self.Config = FastModel('sale.configuration', self.ctx)
@ -313,23 +313,25 @@ class MainWindow(FrontWindow):
)
}
_Tables = self._Tables = None
# _RestTables = None
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 = FastModel('party.consumer', self.ctx)
_Tables = {
'name': '_Tables',
'model': 'sale.shop.table',
'fields': ('name', 'shop', 'capacity', 'state')
}
_PosSale['fields'].extend(['table_assigned', 'table_assigned.name', 'table_assigned.state'])
print('self._sale_pos_restaurant', self._sale_pos_restaurant)
# if self._sale_pos_restaurant:
# self.PartyConsumer = FastModel('party.consumer', self.ctx)
# _RestTables = True
# _RestTables = {
# 'name': '_Tables',
# 'model': 'sale.shop.table',
# 'fields': ('name', 'shop', 'capacity', 'state')
# }
# _PosSale['fields'].extend(['table_assigned', 'table_assigned.name', 'table_assigned.state'])
if self._commission_activated:
_PosSale['fields'].extend(['agent', 'agent.party.name', 'commission'])
# if self._commission_activated:
# _PosSale['fields'].extend(['agent', 'agent.party.name', 'commission'])
self.User = FastModel('res.user', self.ctx)
self._user, = self.User.find([('login', '=', self.user)])
@ -343,8 +345,8 @@ class MainWindow(FrontWindow):
self.ctx['user'] = self._user['id']
self.ModSale = FastModel('sale.sale', self.ctx)
self.ModSaleLine = FastModel('sale.line', self.ctx)
self.Sale = FastModel('sale.sale', self.ctx)
self.SaleLine = FastModel('sale.line', self.ctx)
self.Product = FastModel('product.product', self.ctx)
self.Journal = FastModel('account.statement.journal', self.ctx)
self.Employee = FastModel('company.employee', self.ctx)
@ -360,13 +362,8 @@ class MainWindow(FrontWindow):
if self._commission_activated:
self.Agent = FastModel('commission.agent', self.ctx)
self.Comission = FastModel('commission', self.ctx)
models_to_work = [_PosSale]
if _Tables:
models_to_work.append(_Tables)
# modules.set_models(models_to_work)
if self._sale_pos_restaurant:
self.RestTables = FastModel('sale.shop.table', self.ctx)
self.device, = self.Device.find([
('id', '=', self._user['sale_device']['id']),
@ -453,6 +450,7 @@ class MainWindow(FrontWindow):
if self._commission_activated:
self.dialog_agent = DialogAgent(self).get()
if self.enviroment == 'restaurant' and self._sale_pos_restaurant:
print('Heere... yesss',)
self.dialog_table_sale_consumer = DialogTableSaleConsumer(self).get()
self.dialog_sale_consumer_selected = SaleConsumerSelected(self).get()
self.dialog_search_consumer = DialogConsumer(self).get()
@ -464,7 +462,7 @@ class MainWindow(FrontWindow):
if ">" in self.printer_sale_name:
self.printer_sale_name = str(str("\\") + self.printer_sale_name.replace('>', str('\\')))
ctx_printing = self.ModSale.get_printing_context({
ctx_printing = self.Sale.get_printing_context({
'device_id': self.device['id'],
'user': self.user,
})
@ -506,12 +504,14 @@ class MainWindow(FrontWindow):
# Return sale to draft state
if not self._check_quantity():
return
self._PosSale.to_quote(self._sale['id'])
args = {'sale_id': self._sale['id']}
self.Sale.to_quote(args)
if self.model_sale_lines.rowCount() > 0:
if self.check_salesman():
self.state_disabled()
try:
self.ModSale.generate_shipment({
self.Sale.generate_shipment({
'sale_id': self._sale['id'],
})
self.dialog('order_dispatched')
@ -521,7 +521,7 @@ class MainWindow(FrontWindow):
def button_to_draft_pressed(self):
# Return sale to draft state
if hasattr(self, '_sale'):
self.ModSale.to_draft(self._sale['id'])
self.Sale.to_draft(self._sale['id'])
self.state_disabled()
def create_gui(self):
@ -704,19 +704,19 @@ class MainWindow(FrontWindow):
# 'size': self.screen_size,
# 'color': self.label_color
# }))
DELIVERY_WAY = [
KIND = [
('', ''),
('take_away', self.tr('TAKE AWAY')),
('delivery', self.tr('DELIVERY')),
('table', self.tr('TABLE'))
('to_table', self.tr('TO TABLE'))
]
info_fields.append(
('delivery_way', {
'name': self.tr('DELIVERY WAY'),
('kind', {
'name': self.tr('KIND'),
'placeholder': False,
'type': 'selection',
'on_change': 'action_delivery_way_selection_changed',
'values': DELIVERY_WAY,
'on_change': 'action_kind_selection_changed',
'values': KIND,
'size': self.screen_size,
'color': self.label_color
}))
@ -906,7 +906,7 @@ class MainWindow(FrontWindow):
return False
if self._current_line_id:
self._sale_line['quantity'] = float(quantity)
rec = self.ModSaleLine.faster_set_quantity(self._sale_line)
rec = self.SaleLine.faster_set_quantity(self._sale_line)
except:
return self.message_bar.set('quantity_not_valid')
@ -926,7 +926,7 @@ class MainWindow(FrontWindow):
elif self._sign == '/':
if value <= 0:
return
sale_line, = self.ModSaleLine.find([
sale_line, = self.SaleLine.find([
('id', '=', self._current_line_id)
])
price_w_tax = sale_line['product']['sale_price_w_tax']
@ -1027,7 +1027,7 @@ class MainWindow(FrontWindow):
def set_discount_amount(self):
res = 0
if self._sale['id']:
res = self.ModSale.get_discount_total({
res = self.Sale.get_discount_total({
'sale_id': self._sale['id']
})
self.field_discount.setText(res)
@ -1046,7 +1046,7 @@ class MainWindow(FrontWindow):
def __do_invoice_thread(self):
try:
res = self.ModSale.faster_post_invoice({
res = self.Sale.faster_post_invoice({
'sale_id': self.sale_to_post['id']
})
except:
@ -1058,7 +1058,7 @@ class MainWindow(FrontWindow):
if self.sale_to_post['is_credit']:
return
self.ModSale.reconcile_invoice({
self.Sale.reconcile_invoice({
'sale_id': self.sale_to_post['id']
})
# self.set_state('finished')
@ -1067,17 +1067,18 @@ class MainWindow(FrontWindow):
self._sale['is_credit'] = is_credit
self.sale_to_post = self._sale
self.do_invoice.start()
if self._Tables and self._sale.get('table_assigned'):
self._Tables.write([self._sale['table_assigned']],
{'state': 'available'})
if 1: #try:
if self.RestTables and self._sale.get('table_assigned'):
self.RestTables.write(
[self._sale['table_assigned']], {'state': 'available'}
)
try:
if self.print_receipt == 'automatic':
_copies = self.device['shop']['invoice_copies']
if not is_credit:
self.print_invoice(copies=_copies)
if self.print_order and self.print_auto_order:
self.action_print_order()
else: #except:
except:
logging.error(sys.exc_info()[0])
if not is_credit and self._commission_activated:
@ -1096,13 +1097,13 @@ class MainWindow(FrontWindow):
if not sale_id:
sale_id = self._sale['id']
args = {'sale_id': sale_id}
data = self.ModSale.get_data(args)
data = self.Sale.get_data(args)
for i in range(copies):
self.receipt_sale.print_sale(data)
def button_duplicate_sale(self):
if self.sale_customer_selected:
res = self.ModSale.duplicate_sale({
res = self.Sale.duplicate_sale({
'sale_id': self.sale_customer_selected,
})
self.load_sale(res['sale_id'])
@ -1123,7 +1124,7 @@ class MainWindow(FrontWindow):
('consumer', '=', self._consumer['id']),
]
self.model_sale_consumer.reset()
sales = self.ModSale.find(dom, limit=10)
sales = self.Sale.find(dom, limit=10)
for record in sales:
self.model_sale_consumer.add_record(record)
self.dialog_table_sale_consumer.exec_()
@ -1143,7 +1144,7 @@ class MainWindow(FrontWindow):
if not self.validate_payment_term():
return
sale_id = self._sale['id']
res, msg = self.ModSale.faster_process({'sale_id': sale_id})
res, msg = self.Sale.faster_process({'sale_id': sale_id})
if msg:
self.message_bar.set(msg)
return
@ -1179,10 +1180,10 @@ class MainWindow(FrontWindow):
self.add_product(code=self._config['tip_product']['code'])
self.button_plus_pressed()
eval_value = int((self._config['tip_rate'] / 100) * total_amount)
self.ModSaleLine.write(
self.SaleLine.write(
[self._current_line_id], {'unit_price': Decimal(eval_value)}
)
self.ModSale.write([self._sale['id']], {'tip': Decimal(eval_value)})
self.Sale.write([self._sale['id']], {'tip': Decimal(eval_value)})
self.set_unit_price(eval_value)
self.update_total_amount()
@ -1214,7 +1215,7 @@ class MainWindow(FrontWindow):
def action_open_statement(self):
if not self.dialog_money_count.exec_():
return
res = self.ModSale.faster_open_statement({
res = self.Sale.faster_open_statement({
'device': self.device['id'],
'total_money': Decimal(
self.row_field_total_money.text().replace(',', '')
@ -1228,7 +1229,7 @@ class MainWindow(FrontWindow):
def action_closed_statement(self):
if not self.dialog_money_count.exec_():
return
res = self.ModSale.faster_close_statement({
res = self.Sale.faster_close_statement({
'device': self.device['id'],
'data': self.model_money_count._data,
})
@ -1268,7 +1269,7 @@ class MainWindow(FrontWindow):
self.dialog('customer_not_credit')
return False
self._credit_amount = self.ModSale.get_credit_amount_party({'party_id': self.party_id})
self._credit_amount = self.Sale.get_credit_amount_party({'party_id': self.party_id})
self._credit_limit_amount = party['credit_limit_amount']
if is_credit and self._credit_limit_amount and \
@ -1279,7 +1280,7 @@ class MainWindow(FrontWindow):
def action_payment_term_selection_changed(self):
is_credit = self._payment_terms[str(self.field_payment_term_id)]['is_credit']
self.ModSale.write([self._sale['id']], {'payment_term': self.field_payment_term_id})
self.Sale.write([self._sale['id']], {'payment_term': self.field_payment_term_id})
self.field_payment_term.setText(self._payment_terms[str(self.field_payment_term_id)]['name'])
if is_credit and self.type_pos_user != 'salesman':
if self.validate_credit_limit():
@ -1301,21 +1302,21 @@ class MainWindow(FrontWindow):
def action_delivery_charge_selection_changed(self, index):
val = self.field_delivery_charge.get_id()
if val:
self.ModSale.write([self._sale['id']], {'delivery_charge': val})
self.Sale.write([self._sale['id']], {'delivery_charge': val})
def action_delivery_way_selection_changed(self, index):
val = self.field_delivery_way.get_id()
def action_kind_selection_changed(self, index):
val = self.field_kind.get_id()
if val:
self.ModSale.write([self._sale['id']], {'delivery_way': val})
self.Sale.write([self._sale['id']], {'kind': val})
def action_invoice_type_selection_changed(self, index):
val = self.field_invoice_type.get_id()
if val and self._sale and self._sale.get('id'):
self.ModSale.write([self._sale['id']], {'invoice_type': val})
self.Sale.write([self._sale['id']], {'invoice_type': val})
def action_tax_selection_changed(self):
res = self.ModSale.add_tax(self._sale['id'], self.field_tax_id,
self._context)
res = self.Sale.add_tax(self._sale['id'], self.field_tax_id,
self._context)
self._sale.update(res)
self.set_amounts()
@ -1339,11 +1340,11 @@ class MainWindow(FrontWindow):
sale = {}
if number:
if type_doc in ['order', 'delivery']:
sales = self.ModSale.find([('number', '=', number)])
sales = self.Sale.find([('number', '=', number)])
if sales:
sale = sales[0]
else:
sale = self.ModSale.get_sale_from_invoice([1], number)
sale = self.Sale.get_sale_from_invoice([1], number)
if not sale:
return self.message_bar.set('sale_number_not_found')
sale_id = sale['id']
@ -1374,14 +1375,14 @@ class MainWindow(FrontWindow):
self.dialog_comment.exec_()
comment = self.field_comment_ask.text()
if comment:
self.ModSale.write([self._sale['id']], {'comment': comment})
self.Sale.write([self._sale['id']], {'comment': comment})
def action_position(self):
self.dialog_position.exec_()
position = self.field_position_ask.text()
if hasattr(self, 'field_position') and position:
self.field_position.setText(position)
self.ModSale.write([self._sale['id']], {'position': position})
self.Sale.write([self._sale['id']], {'position': position})
def action_agent(self):
self.dialog_agent.exec_()
@ -1389,7 +1390,7 @@ class MainWindow(FrontWindow):
if not res:
return
commission = float(res)
sale, = self.ModSale.find([
sale, = self.Sale.find([
('id', '=', self._sale['id']),
])
self.field_agent_id = self.field_agent_ask.get_id()
@ -1399,7 +1400,7 @@ class MainWindow(FrontWindow):
('id', '=', self.field_agent_id),
])
if commission <= agent['plan']['percentage']:
self.ModSale.write([self._sale['id']], {
self.Sale.write([self._sale['id']], {
'agent': self.field_agent_id,
'commission': int(commission),
})
@ -1441,16 +1442,15 @@ class MainWindow(FrontWindow):
def _print_order(self, sale_id, kind, reversion=False):
result = False
if 1: #try:
try:
args = {
'sale_id': sale_id,
'reversion': reversion,
'repeat': False,
}
orders = self.ModSale.get_order2print(args)
print(orders)
orders = self.Sale.get_order2print(args)
result = self.receipt_order.print_orders(orders, reversion, kind)
else: #except:
except:
logging.error('Printing order fail!')
return result
@ -1537,7 +1537,7 @@ class MainWindow(FrontWindow):
response = dialog.exec_()
if response == DIALOG_REPLY_NO:
return
self.ModSale.cancel_sale(self._sale['id'])
self.Sale.cancel_sale(self._sale['id'])
self.field_password_for_cancel_ask.setText('')
self.set_state('cancel')
self.clear_right_panel()
@ -1571,7 +1571,7 @@ class MainWindow(FrontWindow):
]
fields = self.dialog_search_sales.fields_names
sales = self.ModSale.find(dom, fields=fields, order=[('id', 'DESC')])
sales = self.Sale.find(dom, fields=fields, order=[('id', 'DESC')])
self.dialog_search_sales.set_from_values(sales)
if self.enviroment == 'retail':
dom_draft = [
@ -1579,7 +1579,7 @@ class MainWindow(FrontWindow):
('state', '=', 'draft'),
('invoice_number', '!=', None),
]
sales_draft = self.ModSale.find(dom_draft)
sales_draft = self.Sale.find(dom_draft)
self.dialog_search_sales.set_counter_control(sales_draft)
response = self.dialog_search_sales.execute()
self.field_invoice_type.set_enabled(True)
@ -1618,13 +1618,13 @@ class MainWindow(FrontWindow):
self.field_payment_term_id = self.default_payment_term['id']
self.field_payment_term.setText(self.default_payment_term['name'])
self.ModSale.write([self._sale['id']], values)
self.Sale.write([self._sale['id']], values)
self.party_id = party_id
self.field_party.setText(party['name'])
if party.get('salesman'):
self.field_salesman_id = party['salesman']['id']
self.ModSale.write([self._sale['id']], {'salesman': self.field_salesman_id})
self.Sale.write([self._sale['id']], {'salesman': self.field_salesman_id})
self.field_salesman.setText(party['salesman']['name'])
# if self._credit_limit_activated:
@ -1640,7 +1640,7 @@ class MainWindow(FrontWindow):
self.clear_data()
self.clear_left_panel()
self.clear_right_panel()
sale, = self.ModSale.find([('id', '=', sale_id)])
sale, = self.Sale.find([('id', '=', sale_id)])
self._sale.update(sale)
self.table_payment_lines.reset()
self.field_order_number.setText(sale['number'] or '')
@ -1655,7 +1655,7 @@ class MainWindow(FrontWindow):
self.field_salesman.setText(sale['salesman']['name'] or '')
self.field_salesman_id = sale['salesman']['id']
res = self.ModSale.get_invoice_type({'sale_id': sale_id})
res = self.Sale.get_invoice_type({'sale_id': sale_id})
if res:
self.field_invoice_type.set_from_id(res['invoice_type'])
@ -1673,8 +1673,8 @@ class MainWindow(FrontWindow):
if sale.get('channel'):
self.field_channel.setText(sale['channel']['rec_name'].upper())
if sale.get('delivery_way'):
self.field_delivery_way.set_from_id(sale['delivery_way'])
if sale.get('kind'):
self.field_kind.set_from_id(sale['kind'])
if sale.get('delivery_party'):
self.field_delivery_men.setText(sale['delivery_party']['name'] or '')
@ -1691,7 +1691,7 @@ class MainWindow(FrontWindow):
self._set_commission_amount(sale['untaxed_amount'], commission)
self.line_ids = [l['id'] for l in sale.get('lines')]
if sale.get('lines'):
lines = self.ModSaleLine.find([
lines = self.SaleLine.find([
('id', 'in', self.line_ids),
])
sale['lines'] = lines
@ -1730,7 +1730,7 @@ class MainWindow(FrontWindow):
def set_amounts(self, res=None):
if not res:
res = self.ModSale.get_amounts({'sale_id': self._sale['id']})
res = self.Sale.get_amounts({'sale_id': self._sale['id']})
self._sale.update(res)
residual_amount = 0
@ -1853,8 +1853,8 @@ class MainWindow(FrontWindow):
def on_selected_salesman(self, salesman_id):
if salesman_id:
self.ModSale.write([self._sale['id']], {'salesman': salesman_id})
sale, = self.ModSale.find([('id', '=', self._sale['id'])])
self.Sale.write([self._sale['id']], {'salesman': salesman_id})
sale, = self.Sale.find([('id', '=', self._sale['id'])])
self.field_salesman.setText(sale['salesman']['name'] or '')
self.field_salesman_id = salesman_id
self.dialog_salesman.close()
@ -1867,8 +1867,8 @@ class MainWindow(FrontWindow):
def on_selected_delivery_men(self, delivery_men_id):
if delivery_men_id:
self.ModSale.write([self._sale['id']], {'delivery_party': delivery_men_id})
sale, = self.ModSale.find([('id', '=', self._sale['id'])])
self.Sale.write([self._sale['id']], {'delivery_party': delivery_men_id})
sale, = self.Sale.find([('id', '=', self._sale['id'])])
self.field_delivery_men.setText(sale['delivery_party']['name'] or '')
self.field_delivery_men_id = delivery_men_id
self.dialog_delivery_men.close()
@ -1885,7 +1885,7 @@ class MainWindow(FrontWindow):
('id', '=', int(channel_id))
])
self.field_channel.setText(channel['rec_name'].upper())
self.ModSale.write([self._sale['id']], {'channel': channel_id})
self.Sale.write([self._sale['id']], {'channel': channel_id})
self.dialog_channel.close()
def on_selected_payment(self, payment_id):
@ -2042,7 +2042,7 @@ class MainWindow(FrontWindow):
self.clear_data()
self.clear_left_panel()
self.message_bar.set('system_ready')
self._sale = self.ModSale.new_sale({
self._sale = self.Sale.new_sale({
'shop': self.shop['id'],
'invoice_type': 'P',
'company': self.company['id'],
@ -2059,8 +2059,8 @@ class MainWindow(FrontWindow):
})
if hasattr(self, 'field_channel'):
self.field_channel.setText('')
if hasattr(self, 'field_delivery_way'):
self.field_delivery_way.set_from_id('')
if hasattr(self, 'field_kind'):
self.field_kind.set_from_id('')
if hasattr(self, 'field_delivery_men'):
self.field_delivery_men.setText('')
@ -2147,7 +2147,7 @@ class MainWindow(FrontWindow):
'product_id': product_id,
'qty': 1
}
res = self.ModSale.faster_add_product(data)
res = self.Sale.faster_add_product(data)
self._sale_line = res
self._current_line_id = res['id']
self.add_sale_line(res)
@ -2456,7 +2456,7 @@ class MainWindow(FrontWindow):
"""Delete product """
self.ModSaleLine.delete([removed_item['id']])
self.SaleLine.delete([removed_item['id']])
self.set_amounts()
self.update_total_amount()
# self.clear_right_panel()
@ -2469,7 +2469,7 @@ class MainWindow(FrontWindow):
if removed_item and self.print_order:
self.action_print_order(self._sale['id'], removed_item)
if self._config['tip_product']['code'] == removed_item['product.code']:
self.ModSale.write([self._sale['id']], {'tip': None})
self.Sale.write([self._sale['id']], {'tip': None})
def set_discount(self, eval_value, lines_ids=[]):
res = False
@ -2486,7 +2486,7 @@ class MainWindow(FrontWindow):
else:
target_lines = lines_ids
records = self.ModSaleLine.faster_set_discount({
records = self.SaleLine.faster_set_discount({
'line_ids': target_lines,
'value': value
})
@ -2499,7 +2499,7 @@ class MainWindow(FrontWindow):
return res
def set_unit_price(self, value):
rec = self.ModSaleLine.set_faster_unit_price({
rec = self.SaleLine.set_faster_unit_price({
'id': self._current_line_id,
'value': value,
})
@ -2518,7 +2518,7 @@ class MainWindow(FrontWindow):
if voucher_number is None or voucher_number == '':
return self.add_payment(amount)
res = self.ModSale.faster_add_payment({
res = self.Sale.faster_add_payment({
'sale_id': self._sale['id'],
'journal_id': self.field_journal_id,
'amount': to_numeric(amount),
@ -2707,7 +2707,7 @@ class MainWindow(FrontWindow):
self.row_field_qty.setValue(float(qty))
value = self.field_combobox_fraction.get_label()
self.state_line['quantity'] = qty
price_ = self.ModSale.get_product_prices({
price_ = self.Sale.get_product_prices({
'ids': [self._sale_line['product']['id']],
'quantity': float(qty),
'sale_id': self._sale['id'],
@ -2734,23 +2734,23 @@ class MainWindow(FrontWindow):
self._sign = '/'
self._process_price(unit_price)
self._sign = None
_record = self.ModSaleLine.write([self._current_line_id], {})
_record = self.SaleLine.write([self._current_line_id], {})
if self.state_line.get('quantity'):
quantity = self.state_line.pop('quantity')
if self._process_quantity(str(quantity)):
_record = self.ModSaleLine.faster_set_quantity({
_record = self.SaleLine.faster_set_quantity({
'id': self._current_line_id,
'quantity': to_float(quantity, 2)
})
if self.state_line.get('description'):
_record = self.ModSaleLine.write([self._current_line_id], {
_record = self.SaleLine.write([self._current_line_id], {
'description': self.state_line['description']
})
if self.state_line.get('note'):
_record = self.ModSaleLine.write([self._current_line_id], {
_record = self.SaleLine.write([self._current_line_id], {
'note': self.state_line['note']
})
if _record:
@ -2768,17 +2768,17 @@ class MainWindow(FrontWindow):
if not self.state_consumer:
return
if self._consumer:
res = self.ModSale.update_consumer({
res = self.Sale.update_consumer({
'id': self._consumer['id'],
'fields': self.state_consumer,
})
else:
res = self.ModSale.create_consumer({
res = self.Sale.create_consumer({
'fields': self.state_consumer,
})
if res['msg'] == 'ok':
self.consumer_id = res['consumer']
self.ModSale.write([self._sale['id']], {'consumer': self.consumer_id})
self.Sale.write([self._sale['id']], {'consumer': self.consumer_id})
if res.get('party'):
self.on_selected_party(res['party'])
@ -2786,14 +2786,14 @@ class MainWindow(FrontWindow):
if not self.state_delivery_party:
return
if hasattr(self, '_delivery_party_selected') and self._delivery_party_selected:
res = self.ModSale.update_delivery_party({
res = self.Sale.update_delivery_party({
'id': self._delivery_party_selected,
'data': self.state_delivery_party
})
self._delivery_party_selected = None
self.model_delivery_party.update_record(res)
else:
res = self.ModSale.create_delivery_party({
res = self.Sale.create_delivery_party({
'data': self.state_delivery_party,
'shop_id': self.ctx['shop']
})
@ -2867,7 +2867,7 @@ class MainWindow(FrontWindow):
self._Tables.write([id], {'state': new_state})
self.ModSale.write([self._sale['id']], {
self.Sale.write([self._sale['id']], {
'table_assigned': table_assigned
})
self.field_table_assigned.setText(name)
@ -2884,7 +2884,7 @@ class MainWindow(FrontWindow):
self.button_history_customer.setVisible(False)
# def print_equivalent_invoice(self, sale_id):
# sale, = self.ModSale.find([('id', '=', sale_id)])
# sale, = self.Sale.find([('id', '=', sale_id)])
# if not sale['invoices']:
# return

View File

@ -5,7 +5,7 @@ from PyQt5.QtWidgets import QGridLayout, QPushButton
DIR_SHARE = os.path.abspath(
os.path.normpath(os.path.join(__file__, '..', '..', 'share')))
__all__ = ['ManageTables']
__all__ = ['ManageTables', 'CallButton']
STATES = {
'available': 'rgb(180, 180, 180)',
@ -57,6 +57,7 @@ class ManageTables(QGridLayout):
self.buttons = {}
positions = [(i, j) for i in range(rows) for j in range(columns)]
for position, value in zip(positions, tables):
print('XXXX == ', position, value)
button = CallButton(value, method)
self.buttons[button.id] = button
self.addWidget(button, *position)

165
app/models.py Normal file
View File

@ -0,0 +1,165 @@
MODELS = {
'ir.module': {
'rec_name': 'name',
'fields': [
'name', 'state'
]
},
'company.company': {
'rec_name': 'rec_name',
'fields': [
'party', 'logo'
],
'binaries': ['logo']
},
'res.user': {
'rec_name': 'name',
'fields': ['name', 'sale_device']
},
'product.category': {
'rec_name': 'name',
'fields': [
'name', 'leasable', 'parent', 'childs', 'name_icon', 'accounting'
]
},
'sale.sale': {
'rec_name': 'number',
'fields': [
'number', 'party', 'salesman.party.name', 'lines', 'sale_date',
'state', 'total_amount_cache', 'salesman', 'payment_term',
'invoices', 'payments', 'untaxed_amount', 'position', 'tax_amount',
'total_amount', 'residual_amount', 'paid_amount', 'invoice',
'invoices', 'delivery_charge', 'price_list', 'agent', 'commission',
'invoice_number', 'invoice.state', 'shipment_address',
'state_string', 'shop', 'delivery_party', 'reference',
'channel', 'channel.rec_name', 'delivery_way', 'consumer',
'delivery_state', 'table_assigned',
]
},
'sale.line': {
'rec_name': 'product',
'fields': [
'product', 'product.template.sale_price_w_tax', 'type',
'quantity', 'unit_price_w_tax', 'product.description', 'note',
'description', 'qty_fraction', 'amount_w_tax', 'unit.symbol',
'product.template.name', 'product.code', 'unit.digits', 'amount',
'discount', 'product.sale_price_w_tax', 'product.quantity',
'order_sended'
]
},
'account.statement.journal': {
'rec_name': 'number',
'fields': ['name', 'require_voucher', 'kind']
},
'company.employee': {
'rec_name': 'rec_name',
'fields': ['rec_name', 'party']
},
'commission.agent': {
'rec_name': 'rec_name',
'fields': [
'active', 'party', 'party.id_number', 'rec_name', 'plan.percentage'
]
},
'sale.delivery_party': {
'rec_name': 'rec_name',
'fields': [
'active', 'party', 'party.id_number', 'party.phone', 'rec_name',
'number_plate', 'type_vehicle',
]
},
'sale.discount': {
'rec_name': 'rec_name',
'fields': ['active', 'name', 'rec_name', 'discount']
},
'sale.web_channel': {
'rec_name': 'rec_name',
'fields': ['id', 'rec_name']
},
'party.consumer': {
'rec_name': 'rec_name',
'fields': ['party', 'id_number', 'rec_name', 'name', 'address',
'phone', 'birthday', 'preferences']
},
'account.invoice.payment_term': {
'rec_name': 'name',
'fields': ['name', 'active']
},
'sale.device': {
'rec_name': 'name',
'fields': [
'name', 'shop', 'shop.company', 'shop.name', 'shop.taxes',
'shop.party', 'journals', 'shop.product_categories', 'journal',
'shop.payment_term', 'shop.warehouse', 'shop.discount_pos_method',
'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',
'shop.debit_note_electronic_authorization', 'shop.delivery_man',
]
},
'sale.shop': {
'rec_name': 'name',
'fields': ['taxes', 'product_categories', 'party', 'invoice_copies',
'warehouse', 'payment_term', 'salesmans', 'delivery_man',
'discounts']
},
'product.product': {
'rec_name': 'rec_name',
'fields': [
'name', 'code', 'barcode', 'write_date', 'description',
'template.sale_price_w_tax', 'template.account_category',
'location.name', 'image', 'image_icon', 'quantity',
'encoded_sale_price', 'location', 'locations', 'uom'
],
'binaries': ['image']
},
'party.party': {
'rec_name': 'name',
'fields': [
'name', 'id_number', 'addresses', 'phone', 'customer_payment_term',
'customer_payment_term.name', 'credit_limit_amount',
'credit_amount', 'street', 'receivable', 'salesman'
]
},
'ir.action.report': {
'rec_name': 'report_name',
'fields': ['action', 'report_name']
},
'sale.configuration': {
'rec_name': 'id',
'fields': [
'tip_product', 'tip_product.code', 'show_description_pos',
'show_position_pos', 'show_stock_pos', 'encoded_sale_price',
'tip_rate', 'password_force_assign', 'show_agent_pos',
'show_product_image', 'show_location_pos', 'show_order_number',
'show_brand', 'show_delivery_charge', 'decimals_digits_quantity',
'password_admin_pos', 'show_fractions', 'discount_pos_method',
'new_sale_automatic', 'default_invoice_type', 'cache_products_local',
'print_invoice_payment',
]
},
'party.address': {
'rec_name': 'name',
'fields': [
'name', 'street'
]
},
'sale.shop.table': {
'rec_name': 'name',
'fields': ['id', 'name', 'state']
},
'account.tax': {
'rec_name': 'name',
'fields': [
'name'
]
},
'commission': {
'rec_name': 'rec_name',
'fields': [
'name'
]
},
}

View File

@ -1,8 +1,9 @@
import requests
from datetime import date
import simplejson as json
from app.models import MODELS
def encoder(obj):
# FIXME: add datetime, buffer, bytes
@ -18,12 +19,21 @@ def encoder(obj):
class FastModel(object):
def __init__(self, model, ctx):
def __init__(self, model, ctx, fields=None):
self.model = model
self.ctx = ctx
api_url = ctx['params']['api_url']
db = ctx['params']['database']
self.api = '/'.join(['http:/', api_url, db])
_model = MODELS.get(model)
self.fields = None
if fields:
self.fields = fields
elif _model.get('fields'):
self.fields = _model['fields']
else:
print('No hay model ', model)
def __getattr__(self, name, *args):
'Return attribute value'
@ -34,6 +44,8 @@ class FastModel(object):
if ctx:
self.ctx.update(ctx)
route = self.get_route('search')
if not fields:
fields = self.fields
args_ = {
'model': self.model,
'domain': domain,