presik_pos/app/mainwindow.py

2752 lines
98 KiB
Python
Raw Normal View History

2020-04-19 17:54:08 +02:00
#!/usr/bin/env python
# -*- coding: UTF-8 -*-
import sys
import os
import logging
2020-09-03 06:00:57 +02:00
import base64
2020-04-19 17:54:08 +02:00
from decimal import Decimal
from datetime import datetime, timedelta, date
2020-12-23 14:41:33 +01:00
from collections import OrderedDict
2020-12-23 14:04:57 +01:00
from PyQt5.QtCore import Qt, QDate
from .tools import get_icon, to_float, to_numeric
2020-12-09 04:52:42 +01:00
from PyQt5.QtWidgets import (
2020-12-24 15:07:38 +01:00
QLabel, QHBoxLayout, QVBoxLayout, QWidget, QLineEdit, QGridLayout,
QSizePolicy, QFrame
2020-12-09 04:52:42 +01:00
)
2020-12-23 19:25:16 +01:00
2020-12-23 14:04:57 +01:00
from .frontwindow import FrontWindow
2020-06-12 04:36:27 +02:00
from app.commons.action import Action
2020-07-28 23:54:15 +02:00
from app.commons.forms import GridForm, ComboBox, FieldNumeric
2020-06-12 04:36:27 +02:00
from app.commons.messages import MessageBar
2020-12-24 15:07:38 +01:00
2020-06-12 04:36:27 +02:00
from app.commons.table import TableView
2020-12-20 12:14:56 +01:00
from app.commons.model import TableModel, TableModelEdit
2020-06-12 04:36:27 +02:00
from app.commons.menu_buttons import MenuDash
2020-12-29 20:32:42 +01:00
from .localdb import LocalDB
2020-04-19 17:54:08 +02:00
from .reporting import Receipt
2020-12-27 17:30:02 +01:00
from .buttonpad import ButtonsStacked, ButtonsFunction, StartButtons
2020-04-19 17:54:08 +02:00
from .states import STATES, RE_SIGN
2020-12-23 19:25:16 +01:00
from .commons.custom_button import CustomButton
2020-12-23 14:04:57 +01:00
from .threads import DoInvoice
2020-12-29 20:32:42 +01:00
from .store import StoreView
2020-12-06 01:37:57 +01:00
from .constants import (
PATH_PRINTERS, DELTA_LOCALE, STRETCH, alignRight, alignLeft, alignCenter,
2020-12-27 20:06:21 +01:00
alignHCenter, DIALOG_REPLY_NO, ZERO, RATE_CREDIT_LIMIT,
2020-12-24 15:07:38 +01:00
CONVERSION_DIGITS, MONEY, MINIMUM_DATE,
2020-12-06 01:37:57 +01:00
)
2020-12-29 20:32:42 +01:00
from .dialogs import DialogDeliveryParty
2020-04-19 17:54:08 +02:00
2020-12-23 18:24:47 +01:00
invoice_type = [('P', ('POS'))]
2020-07-22 15:21:15 +02:00
2020-04-19 17:54:08 +02:00
class MainWindow(FrontWindow):
def __init__(self, connection, params):
title = "PRESIK | SMART POS"
global CONNECTION
CONNECTION = connection
super(MainWindow, self).__init__(connection, params, title)
self.payment_ctx = {}
self.set_keys()
self.stock_context = None
2020-12-24 00:00:39 +01:00
self._sale = {}
2020-04-19 17:54:08 +02:00
self.ctx = self._context
self.ctx['params'] = params
response = self.load_modules()
if response is not True:
d = self.dialog(response)
d.exec_()
super(MainWindow, self).close()
return
self.setup_sale_line()
2020-09-15 04:53:44 +02:00
self.setup_delivery_party()
2020-09-17 04:41:10 +02:00
self.setup_sale_consumer()
2020-04-19 17:54:08 +02:00
self.setup_payment()
self.set_domains()
2020-09-09 21:22:35 +02:00
self.setup_money_count()
2020-04-19 17:54:08 +02:00
self.create_gui()
self.message_bar.load_stack(self.stack_msg)
2020-12-31 02:39:43 +01:00
self.journal = {}
2020-04-19 17:54:08 +02:00
if not hasattr(self, 'auto_print_commission'):
self.auto_print_commission = False
self.active_usb_printers = []
if os.name == 'posix' and os.path.exists(PATH_PRINTERS):
self.set_printers_usb(PATH_PRINTERS)
self.set_printing_context()
2020-12-06 05:09:41 +01:00
self.create_statusbar()
2020-04-19 17:54:08 +02:00
self.reader_thread = None
self._current_line_id = None
self._amount_text = ''
self._sign = None
self.create_dialogs()
2020-12-23 18:24:47 +01:00
if self.sale_automatic:
self.create_new_sale()
2020-04-19 17:54:08 +02:00
if not hasattr(self, 'active_weighing'):
self.active_weighing = False
elif self.active_weighing is True:
from .electronic_scale import ScaleReader
self.reader_thread = ScaleReader()
self.reader_thread.sigSetWeight.connect(self.set_weight_readed)
self.do_invoice = DoInvoice(self, self._context)
self.do_invoice.sigDoInvoice.connect(self.__do_invoice_thread)
2020-12-27 20:06:21 +01:00
self.set_state('disabled')
2020-12-29 20:32:42 +01:00
sale_fields = [
'number', 'party', 'sale_date', 'comment', 'position',
'description', 'invoice_number', 'tip_amount', 'delivery_amount',
'salesman', 'state', 'kind', 'channel', 'reference',
2020-12-30 15:42:08 +01:00
'invoice_type', 'consumer', 'delivery_party', 'table_assigned'
2020-12-29 20:32:42 +01:00
]
self.store = StoreView(self, sale_fields)
2020-08-21 07:24:00 +02:00
if self.cache_local:
2020-09-16 01:23:40 +02:00
self.set_cache_company()
2020-08-21 07:24:00 +02:00
self.set_cache_products()
2020-12-31 02:21:43 +01:00
for j in self._journals:
if j['id'] == self.default_journal['id']:
self.default_journal = j
2020-04-19 17:54:08 +02:00
def set_domains(self):
self.domain_search_product = [
('code', '!=', None),
('active', '=', True),
('template.salable', '=', True),
('template.account_category', '!=', None),
]
if self.shop['product_categories']:
self.domain_search_product.append(
('account_category', 'in', self.shop['product_categories'])
)
def set_cache_company(self):
2020-12-29 20:32:42 +01:00
self.local_db = LocalDB()
self.local_db.create_table_config()
self._local_config = self.local_db.get_config()
2020-04-19 17:54:08 +02:00
if not self._local_config:
2020-04-23 22:52:05 +02:00
company_id = self.device['shop']['company']['id']
2020-12-29 20:32:42 +01:00
self._local_config = self.local_db.set_config([company_id])
2020-04-19 17:54:08 +02:00
def set_cache_products(self):
2020-12-29 20:32:42 +01:00
self.local_db.create_table_product()
local_products = self.local_db.get_local_products()
2020-04-19 17:54:08 +02:00
2020-12-29 20:32:42 +01:00
config = self.local_db.get_config()
2020-04-19 17:54:08 +02:00
_sync_date = config[1]
2020-08-21 07:24:00 +02:00
products = self.Product.sync_get_products({
'write_date': _sync_date,
'shop_id': self.ctx['shop']
})
2020-12-29 20:32:42 +01:00
self.local_db.update_products(products, local_products)
2020-04-19 17:54:08 +02:00
now = datetime.now()
2020-12-29 20:32:42 +01:00
self.local_db.set_config_sync(str(now))
2020-04-19 17:54:08 +02:00
def set_printers_usb(self, PATH_PRINTERS):
for usb_dev in os.listdir(PATH_PRINTERS):
if 'lp' not in usb_dev:
continue
path_device = os.path.join(PATH_PRINTERS, usb_dev)
self.active_usb_printers.append(['usb', path_device])
def get_current_sale(self):
if hasattr(self, '_sale') and self._sale['id']:
2020-12-20 12:14:56 +01:00
sales = self.Sale.find([
2020-04-19 17:54:08 +02:00
('id', '=', self._sale['id'])
])
if not sales:
return
return sales[0]
def check_empty_sale(self):
sale = self.get_current_sale()
if sale and self.model_sale_lines.rowCount() == 0 \
and sale['state'] == 'draft' and not sale['number']:
self.delete_current_sale()
def delete_current_sale(self):
if self._sale['id']:
2020-12-23 19:08:37 +01:00
args = {'id': self._sale['id']}
self.Sale.cancel_sale(args)
2020-04-19 17:54:08 +02:00
def set_printing_context(self):
# Printing invoice context
if self.printer_sale_name:
if ">" in self.printer_sale_name:
self.printer_sale_name = str(str("\\") + self.printer_sale_name.replace('>', str('\\')))
2020-12-20 12:14:56 +01:00
ctx_printing = self.Sale.get_printing_context({
2020-12-20 02:23:30 +01:00
'device_id': self.device['id'],
'user': self.user,
})
2020-04-19 17:54:08 +02:00
ctx_printing['row_characters'] = self.row_characters
ctx_printing['delta_locale'] = DELTA_LOCALE
2020-09-03 06:00:57 +02:00
locale_logo = ''
if self.logo:
locale_logo = os.path.join(os.path.abspath(
os.path.dirname(__file__)), 'logo.png')
f = open(locale_logo, "wb")
f.write(base64.decodestring(self.logo.encode()))
f.close()
self.receipt_sale = Receipt(ctx_printing, logo=locale_logo)
2020-04-19 17:54:08 +02:00
# Printing order context
if self.print_order:
self.receipt_order = Receipt(ctx_printing)
self.set_default_printer()
def set_default_printer(self, printer=None):
if self.active_usb_printers:
self.printer_sale_name = self.active_usb_printers[0]
if not printer and self.printer_sale_name:
printer = {
'interface': self.printer_sale_name[0],
'device': self.printer_sale_name[1],
2020-07-28 23:54:15 +02:00
'profile': self.profile_printer,
2020-04-19 17:54:08 +02:00
}
if printer:
self.receipt_sale.set_printer(printer)
def button_new_sale_pressed(self):
2020-12-23 14:04:57 +01:00
self.create_new_sale()
2020-04-19 17:54:08 +02:00
def button_send_to_pay_pressed(self):
# Return sale to draft state
2020-07-27 06:17:17 +02:00
if not self._check_quantity():
return
2020-12-20 12:14:56 +01:00
args = {'sale_id': self._sale['id']}
self.Sale.to_quote(args)
2020-04-19 17:54:08 +02:00
if self.model_sale_lines.rowCount() > 0:
if self.check_salesman():
2020-12-26 22:09:28 +01:00
# self.state_disabled()
pass
try:
2020-12-20 12:14:56 +01:00
self.Sale.generate_shipment({
'sale_id': self._sale['id'],
})
self.dialog('order_dispatched')
except:
self.dialog('error_order_dispatched')
2020-10-15 04:36:38 +02:00
2020-11-06 21:02:01 +01:00
def button_to_draft_pressed(self):
# Return sale to draft state
if hasattr(self, '_sale'):
2020-12-20 12:14:56 +01:00
self.Sale.to_draft(self._sale['id'])
2020-12-26 22:09:28 +01:00
# self.state_disabled()
2020-11-06 21:02:01 +01:00
2020-04-19 17:54:08 +02:00
def create_gui(self):
panels = QHBoxLayout()
2020-12-27 17:30:02 +01:00
panels.setSpacing(0)
panels.setContentsMargins(0, 0, 0, 0)
2020-12-06 01:37:57 +01:00
panel_left = QWidget()
panel_left.setObjectName('panel_left')
vbox_left = QVBoxLayout()
2020-12-27 17:30:02 +01:00
vbox_left.setSpacing(0)
vbox_left.setContentsMargins(0, 0, 0, 0)
2020-12-24 15:07:38 +01:00
2020-12-06 01:37:57 +01:00
if self.screen_size == 'small':
max_size = 620
else:
2020-12-09 04:52:42 +01:00
max_size = 1300
2020-12-06 01:37:57 +01:00
panel_left.setMaximumWidth(max_size)
panel_left.setLayout(vbox_left)
2020-12-27 17:30:02 +01:00
panel_left.setContentsMargins(0, 0, 0, 0)
2020-12-06 01:37:57 +01:00
2020-12-27 20:06:21 +01:00
self.panel_right = QVBoxLayout()
self.panel_right.setSpacing(4)
self.panel_right.setObjectName('panel_right')
self.panel_right.setContentsMargins(3, 3, 3, 3)
2020-04-19 17:54:08 +02:00
left_head = QHBoxLayout()
2020-12-27 17:30:02 +01:00
left_head.setSpacing(4)
2020-12-06 01:37:57 +01:00
left_invoice = QHBoxLayout()
2020-12-27 17:30:02 +01:00
left_invoice.setSpacing(4)
2020-04-19 17:54:08 +02:00
2020-12-23 18:24:47 +01:00
board = QVBoxLayout()
2020-12-27 17:30:02 +01:00
board.setSpacing(0)
2020-12-23 18:24:47 +01:00
# CREATE START FRONT
self.start_front = QWidget()
2020-12-27 17:30:02 +01:00
self.start_front.setObjectName('start_front')
2020-12-23 18:24:47 +01:00
start_front = StartButtons(self)
self.start_front.setLayout(start_front)
# CREATE ORDER FRONT
self.order_front = QWidget()
2020-12-27 17:30:02 +01:00
self.order_front.setObjectName('order_front')
2020-12-23 18:24:47 +01:00
vbox_order_front = QVBoxLayout()
2020-12-27 17:30:02 +01:00
vbox_order_front.setSpacing(4)
2020-12-23 18:24:47 +01:00
vbox_order_front.addLayout(left_head)
vbox_order_front.addLayout(left_invoice)
self.order_front.setLayout(vbox_order_front)
# CONFIGURE BOARD
2020-12-24 15:07:38 +01:00
board.addWidget(self.start_front, 0)
board.addWidget(self.order_front, 0)
2020-12-23 18:24:47 +01:00
2020-12-06 01:37:57 +01:00
# LEFT HEAD COMPONENTS
2020-12-23 19:25:16 +01:00
start_front = CustomButton(
self,
id='button_start',
size=self.screen_size,
icon=get_icon('start_front'),
2020-12-29 04:59:14 +01:00
title=self.tr('START'),
2020-12-23 19:25:16 +01:00
method='see_start_front',
2020-12-27 01:33:17 +01:00
name_style='mini_button',
2020-12-23 19:25:16 +01:00
)
2020-04-19 17:54:08 +02:00
self.message_bar = MessageBar()
2020-07-28 23:54:15 +02:00
self.field_amount = FieldNumeric(self, 'amount', {})
2020-04-19 17:54:08 +02:00
self.field_amount.setObjectName('field_amount')
self.field_sign = QLabel(' ')
self.field_sign.setObjectName('field_sign')
2020-12-23 19:25:16 +01:00
left_head.addWidget(start_front, 0)
2020-12-06 01:37:57 +01:00
left_head.addLayout(self.message_bar, 1)
left_head.addWidget(self.field_sign, 0)
left_head.addWidget(self.field_amount, 1)
# LEFT INVOICE COMPONENTS
self.label_input = QLabel()
2020-12-24 00:53:28 +01:00
# self.label_input.setFocus()
2020-12-06 01:37:57 +01:00
self.label_input.setObjectName('label_input')
size_input = 100
if self.screen_size == 'large':
2020-12-06 05:09:41 +01:00
size_input = 300
2020-12-06 01:37:57 +01:00
self.label_input.setMaximumWidth(size_input)
2020-07-27 06:17:17 +02:00
if self.shop.get('manual_authorization'):
2020-12-10 05:11:52 +01:00
invoice_type.append(('M', 'MANUAL'))
2020-07-27 06:17:17 +02:00
if self.shop.get('electronic_authorization'):
2020-12-10 05:11:52 +01:00
invoice_type.append(('1', ('VENTA ELECTRONICA')))
2020-07-27 06:17:17 +02:00
2020-12-23 18:24:47 +01:00
self.field_invoice_type = ComboBox(self, 'invoice_type', {
'values': invoice_type,
'on_change': 'action_invoice_type_selection_changed'
})
2020-04-19 17:54:08 +02:00
2020-12-06 01:37:57 +01:00
left_invoice.addWidget(self.label_input, 1)
2020-12-06 05:09:41 +01:00
left_invoice.addWidget(self.field_invoice_type, 0)
2020-04-19 17:54:08 +02:00
2020-12-06 01:37:57 +01:00
self.field_invoice = QLineEdit('')
self.field_invoice.setReadOnly(True)
self.field_invoice.setObjectName('field_invoice')
2020-12-27 17:30:02 +01:00
self.field_invoice.setPlaceholderText(self.tr('No Invoice'))
2020-12-06 01:37:57 +01:00
left_invoice.addWidget(self.field_invoice, 1)
self.field_state = QLineEdit('STATE')
self.field_state.setReadOnly(True)
self.field_state.setObjectName('field_state')
left_invoice.addWidget(self.field_state)
# LEFT TABLE COMPONENTS
values = self.get_menu_control_panel()
2020-12-09 21:05:09 +01:00
self.menu_control_panel = ButtonsFunction(self, values=values)
2020-12-27 17:30:02 +01:00
button_functions = ButtonsFunction(self)
2020-12-06 01:37:57 +01:00
2020-04-19 17:54:08 +02:00
info_fields = [
('party', {
'name': self.tr('CUSTOMER'),
'readonly': True,
'placeholder': False,
'size': self.screen_size,
'color': self.label_color
2020-04-19 17:54:08 +02:00
}),
2020-12-29 20:32:42 +01:00
('sale_date', {
2020-04-19 17:54:08 +02:00
'name': self.tr('DATE'),
'readonly': True,
'placeholder': False,
'size': self.screen_size,
'color': self.label_color
2020-04-19 17:54:08 +02:00
}),
('salesman', {
'name': self.tr('SALESMAN'),
'readonly': True,
'placeholder': False,
'size': self.screen_size,
'color': self.label_color
2020-04-19 17:54:08 +02:00
}),
2020-12-29 20:32:42 +01:00
('number', {
2020-04-19 17:54:08 +02:00
'name': self.tr('No ORDER'),
'placeholder': False,
'readonly': True,
'size': self.screen_size,
'color': self.label_color
2020-04-19 17:54:08 +02:00
}),
('payment_term', {
'name': self.tr('PAYMENT TERM'),
'readonly': True,
2020-12-06 05:09:41 +01:00
'invisible': False,
2020-04-19 17:54:08 +02:00
'placeholder': False,
'size': self.screen_size,
'color': self.label_color
2020-04-19 17:54:08 +02:00
}),
2020-12-29 20:32:42 +01:00
('delivery_party', {
2020-09-03 06:00:57 +02:00
'name': self.tr('DELIVERY MEN'),
'placeholder': False,
'size': self.screen_size,
'color': self.label_color
})
2020-04-19 17:54:08 +02:00
]
2020-09-03 06:00:57 +02:00
if self._web_channel:
self.channels = self.Channel.find([])
info_fields.append(
('channel', {
'name': self.tr('CHANNEL'),
'readonly': True,
2020-09-03 06:00:57 +02:00
'placeholder': False,
'size': self.screen_size,
'color': self.label_color
}))
2020-12-06 05:09:41 +01:00
if self._config['show_position_pos']:
2020-04-19 17:54:08 +02:00
info_fields.append(('position', {
'name': self.tr('POSITION'),
'readonly': True,
'placeholder': False,
'size': self.screen_size,
'color': self.label_color
2020-04-19 17:54:08 +02:00
}))
2020-12-06 05:09:41 +01:00
if self._commission_activated and self._config['show_agent_pos']:
2020-04-19 17:54:08 +02:00
info_fields.append(('agent', {
'name': self.tr('AGENT'),
2020-12-06 05:09:41 +01:00
'placeholder': False,
2020-04-19 17:54:08 +02:00
'readonly': True,
'size': self.screen_size,
'color': self.label_color
2020-04-19 17:54:08 +02:00
}))
_cols = 2
self.field_delivery_charge = None
if self._config['show_delivery_charge']:
info_fields.append(
('delivery_charge', {
'name': self.tr('DELIVERY CHARGE'),
'placeholder': False,
'type': 'selection',
'on_change': 'action_delivery_charge_selection_changed',
'values': [
('', ''),
('customer', self.tr('CUSTOMER')),
('company', self.tr('COMPANY')),
],
'size': self.screen_size,
'color': self.label_color
2020-04-19 17:54:08 +02:00
}))
self.field_table_assigned = None
2020-09-03 06:00:57 +02:00
if self._sale_pos_restaurant:
2020-12-20 22:52:28 +01:00
info_fields.append(
('consumer', {
'name': self.tr('CONSUMER'),
'placeholder': False,
'size': self.screen_size,
'color': self.label_color
}))
2020-12-20 12:14:56 +01:00
KIND = [
2020-09-18 19:06:26 +02:00
('', ''),
('take_away', self.tr('TAKE AWAY')),
('delivery', self.tr('DELIVERY')),
2020-12-20 12:14:56 +01:00
('to_table', self.tr('TO TABLE'))
2020-09-18 19:06:26 +02:00
]
2020-07-22 06:26:51 +02:00
info_fields.append(
2020-12-20 12:14:56 +01:00
('kind', {
'name': self.tr('KIND'),
2020-07-22 06:26:51 +02:00
'placeholder': False,
2020-08-20 06:40:41 +02:00
'type': 'selection',
2020-12-20 12:14:56 +01:00
'on_change': 'action_kind_selection_changed',
'values': KIND,
2020-07-22 06:26:51 +02:00
'size': self.screen_size,
'color': self.label_color
}))
2020-12-31 21:50:37 +01:00
PAYMENT_METHODS = [
('', ''),
('cash', self.tr('CASH')),
('terminal', self.tr('TERMINAL')),
]
info_fields.append(
('payment_method', {
'name': self.tr('PAYMENT METHOD'),
'placeholder': False,
'type': 'selection',
'on_change': 'action_payment_method_selection_changed',
'values': PAYMENT_METHODS,
'size': self.screen_size,
'color': self.label_color
}))
2020-04-19 17:54:08 +02:00
info_fields.append(
('table_assigned', {
'name': self.tr('ASSIGNED TABLE'),
'placeholder': False,
'size': self.screen_size,
'color': self.label_color
2020-04-19 17:54:08 +02:00
}))
col_sizes_tlines = [field['width'] for field in self.fields_sale_line]
2020-12-10 13:05:54 +01:00
self.table_sale_lines = TableView('model_sale_lines',
2020-12-06 01:37:57 +01:00
self.model_sale_lines, col_sizes_tlines,
method_selected_row=self.sale_line_selected
)
2020-04-19 17:54:08 +02:00
for i, f in enumerate(self.model_sale_lines._fields, 0):
if f.get('invisible'):
self.table_sale_lines.hideColumn(i)
2020-12-06 05:09:41 +01:00
invisible = False
if self.enviroment == 'restaurant':
invisible = True
_fields_amounts = [
2020-04-19 17:54:08 +02:00
('untaxed_amount', {
'name': self.tr('SUBTOTAL'),
'readonly': True,
'type': 'money',
'size': self.screen_size,
2020-12-06 05:09:41 +01:00
'color': self.label_color,
'invisible': invisible,
2020-04-19 17:54:08 +02:00
}),
('taxes_amount', {
'name': self.tr('TAXES'),
'readonly': True,
'type': 'money',
'size': self.screen_size,
2020-12-06 05:09:41 +01:00
'color': self.label_color,
'invisible': invisible,
2020-04-19 17:54:08 +02:00
}),
('discount', {
'name': self.tr('DISCOUNT'),
'readonly': True,
'type': 'money',
'size': self.screen_size,
2020-12-06 05:09:41 +01:00
'color': self.label_color,
'invisible': invisible,
2020-04-19 17:54:08 +02:00
}),
2020-12-24 00:00:39 +01:00
('tip_amount', {
'name': self.tr('VR. PROPINA'),
'type': 'money',
'size': self.screen_size,
'color': self.label_color,
}),
('delivery_amount', {
'name': self.tr('VR. DOMIC'),
'type': 'money',
'size': self.screen_size,
'color': self.label_color,
}),
2020-04-19 17:54:08 +02:00
('total_amount', {
'name': self.tr('TOTAL'),
'readonly': True,
'type': 'money',
'size': self.screen_size,
2020-12-10 05:11:52 +01:00
'color': 'black',
'font_size': 'big',
2020-04-19 17:54:08 +02:00
}),
2020-12-24 00:00:39 +01:00
('net_amount', {
2020-12-24 00:53:28 +01:00
'name': self.tr('NETO TOTAL'),
2020-12-24 00:00:39 +01:00
'readonly': True,
'type': 'money',
'size': self.screen_size,
'color': 'black',
'font_size': 'big',
}),
2020-12-30 15:42:08 +01:00
('paid_amount', {
2020-04-19 17:54:08 +02:00
'name': self.tr('PAID'),
'readonly': True,
'type': 'money',
'size': self.screen_size,
2020-12-06 05:09:41 +01:00
'color': self.label_color,
2020-04-19 17:54:08 +02:00
}),
2020-12-30 15:42:08 +01:00
('residual_amount', {
'name': self.tr('PENDING'),
2020-04-19 17:54:08 +02:00
'readonly': True,
'type': 'money',
'size': self.screen_size,
'color': self.label_color_2 or 'blue'
2020-04-19 17:54:08 +02:00
}),
('change', {
'name': self.tr('CHANGE'),
'readonly': True,
'type': 'money',
'size': self.screen_size,
'color': self.label_color_2 or 'orange'
2020-04-19 17:54:08 +02:00
})
]
fields_amounts = OrderedDict(_fields_amounts)
self.grid_amounts = GridForm(self, fields_amounts, col=1)
2020-12-27 17:30:02 +01:00
self.buttons_stacked = ButtonsStacked(self)
2020-12-24 15:07:38 +01:00
2020-12-06 01:37:57 +01:00
self.table_payment = TableView('table_payment',
self.table_payment_lines, [250, STRETCH])
2020-12-23 18:24:47 +01:00
2020-12-24 15:07:38 +01:00
self.grid_info = GridForm(self, OrderedDict(info_fields), col=_cols)
2020-12-27 17:30:02 +01:00
2020-12-23 18:24:47 +01:00
vbox_order_front.addWidget(self.table_sale_lines, 1)
vbox_left.addLayout(board, 0)
2020-08-20 06:40:41 +02:00
2020-04-19 17:54:08 +02:00
if self.enviroment == 'restaurant':
2020-12-29 03:13:18 +01:00
self.panel_right_box = QWidget()
values = self.get_product_by_categories()
self.menu_dash = MenuDash(self, values, 'on_selected_item')
2020-12-23 18:24:47 +01:00
self.order_front.hide()
2020-12-27 17:30:02 +01:00
vbox_order_front.addLayout(button_functions, 0)
vbox_order_front.addLayout(self.grid_info, 0)
2020-12-29 03:13:18 +01:00
self.panel_right.addWidget(self.menu_dash, 1)
2020-12-27 20:06:21 +01:00
_panel_right_box = QVBoxLayout()
_panel_right_box.addLayout(self.grid_amounts, 0)
_panel_right_box.addLayout(self.buttons_stacked, 0)
self.panel_right_box.setLayout(_panel_right_box)
self.panel_right.addWidget(self.panel_right_box)
2020-04-19 17:54:08 +02:00
else:
2020-12-09 04:52:42 +01:00
vbox_left.addLayout(self.grid_info, 1)
2020-12-27 20:06:21 +01:00
self.panel_right.addLayout(self.grid_amounts, 1)
self.panel_right.addLayout(button_functions, 1)
self.panel_right.addLayout(self.buttons_stacked, 0)
self.panel_right.addWidget(self.table_payment)
2020-04-19 17:54:08 +02:00
2020-12-06 01:37:57 +01:00
panels.addWidget(panel_left, 1)
2020-12-27 20:06:21 +01:00
panels.addLayout(self.panel_right, 0)
2020-04-19 17:54:08 +02:00
widget = QWidget()
widget.setLayout(panels)
self.setCentralWidget(widget)
2020-12-27 20:06:21 +01:00
def show_right_panel(self, bool):
if bool:
self.panel_right_box.show()
else:
self.panel_right_box.hide()
2020-04-19 17:54:08 +02:00
def button_plus_pressed(self):
error = False
if self._input_text == '' and self._amount_text == '0':
return
if self._state in ('paid', 'disabled'):
return
if self._sign in ('*', '-', '/'):
if hasattr(self, '_sale_line') and self._sale_line \
2020-07-27 06:17:17 +02:00
and self._sale_line.get('type') and self._state == 'add' \
and self.model_sale_lines.rowCount() > 0:
2020-04-19 17:54:08 +02:00
if self._sign == '*':
self._process_quantity(self._amount_text)
else:
error = not(self._process_price(self._amount_text))
elif self._state in ['add', 'cancel', 'accept']:
self.clear_right_panel()
self.add_product(code=self._input_text)
2020-12-27 20:06:21 +01:00
elif self._state == 'payment':
2020-04-19 17:54:08 +02:00
is_paid = self._process_pay(self.field_amount.text())
if not is_paid:
2020-12-27 20:06:21 +01:00
self.set_state('payment')
2020-04-19 17:54:08 +02:00
self.clear_input_text()
self.clear_amount_text()
return
2020-12-27 20:06:21 +01:00
self.set_state('finished')
2020-04-19 17:54:08 +02:00
else:
logging.warning('Unknown command/text')
self._clear_context(error)
2020-12-23 19:25:16 +01:00
def see_start_front(self):
self.change_view_to('start_front')
2020-12-23 18:24:47 +01:00
def change_view_to(self, to_view):
if to_view == 'start_front':
self.order_front.hide()
self.start_front.show()
else:
self.start_front.hide()
self.order_front.show()
2020-04-19 17:54:08 +02:00
def action_read_weight(self):
self.reader_thread.start()
def set_weight_readed(self):
if not self.reader_thread or not self.reader_thread.best_weight:
return
if self.reader_thread.best_weight:
self.amount_text_changed(self.reader_thread.best_weight)
self._process_quantity(self._amount_text)
self._clear_context(False)
self.reader_thread.fZERO()
def _clear_context(self, error=False):
self.clear_input_text()
self.clear_amount_text()
self.clear_sign()
2020-07-27 06:17:17 +02:00
if self.state == 'disabled':
self.message_bar.set('not_sale')
2020-12-27 20:06:21 +01:00
elif self._state not in ('warning', 'cash', 'payment') and not error:
2020-04-19 17:54:08 +02:00
self.message_bar.set('system_ready')
else:
self.set_state('add')
def _process_quantity(self, text):
eval_value = text.replace(',', '.')
rec = {}
2020-12-10 13:09:40 +01:00
try:
2020-04-19 17:54:08 +02:00
quantity = Decimal(eval_value)
2020-09-12 18:12:22 +02:00
product_id = self.product_id
2020-12-10 13:05:54 +01:00
if product_id and self.stock_context:
2020-12-10 13:09:40 +01:00
_product, = self.Product.find([
('id', '=', product_id)],
ctx=self.stock_context
)
2020-10-15 22:37:12 +02:00
if _product and 'quantity' in _product:
2020-09-12 18:12:22 +02:00
if not self._check_stock_quantity(_product, quantity):
return False
2020-04-19 17:54:08 +02:00
if self._current_line_id:
2020-12-11 22:47:46 +01:00
self._sale_line['quantity'] = float(quantity)
2020-12-26 22:09:28 +01:00
args = {
'id': self._sale_line['id'],
'quantity': quantity,
}
rec = self.SaleLine.faster_set_quantity(args)
2020-12-10 13:09:40 +01:00
except:
return self.message_bar.set('quantity_not_valid')
2020-04-19 17:54:08 +02:00
self.message_bar.set('system_ready')
self.model_sale_lines.update_record(rec)
2020-12-30 01:02:54 +01:00
self.set_amounts()
2020-04-19 17:54:08 +02:00
def _process_price(self, text):
discount_valid = True
eval_value = text.replace(',', '')
value = float(eval_value)
if self._sign == '-':
if self.discount_method == 'percentage' and value > 90:
discount_valid = False
else:
discount_valid = self.set_discount(eval_value)
elif self._sign == '/':
if value <= 0:
return
2020-12-20 12:14:56 +01:00
sale_line, = self.SaleLine.find([
2020-04-19 17:54:08 +02:00
('id', '=', self._current_line_id)
])
2020-07-09 00:37:50 +02:00
price_w_tax = sale_line['product']['sale_price_w_tax']
2020-04-19 17:54:08 +02:00
if price_w_tax <= Decimal(value):
# Change unit price
discount_valid = self.set_unit_price(value)
2020-07-09 00:37:50 +02:00
self.set_discount(0)
2020-04-19 17:54:08 +02:00
else:
eval_value = (1 - (value / price_w_tax)) * 100
if self.discount_method == 'fixed':
eval_value = price_w_tax - value
discount_valid = self.set_discount(eval_value)
if not discount_valid:
self.message_bar.set('discount_not_valid')
return False
self.message_bar.set('system_ready')
2020-12-30 01:02:54 +01:00
self.set_amounts()
2020-04-19 17:54:08 +02:00
return True
def _process_pay(self, text):
if not self.validate_done_sale():
return
val = Decimal(text.replace(',', ''))
2020-12-31 02:21:43 +01:00
# FIXME
# if self._commission_activated:
# if self._journals[self.field_journal_id]['kind'] == 'payment':
# agent_id = None
# if self.field_agent_id:
# agent_id = self.field_agent_id
# else:
# agent_id = self.field_agent_ask.get_id()
#
# if not agent_id:
# self.message_bar.set('missing_agent')
# return False
2020-04-19 17:54:08 +02:00
cash_received = Decimal(val)
self.set_amounts()
2020-12-30 15:42:08 +01:00
# residual_amount = self._sale['residual_amount']
residual_amount = self.store.get('residual_amount')
if residual_amount <= 0:
2020-04-19 17:54:08 +02:00
# The sale is paid
self._done_sale()
return True
2020-12-20 02:23:30 +01:00
change = float(cash_received) - residual_amount
2020-04-19 17:54:08 +02:00
if residual_amount >= cash_received:
amount_to_add = cash_received
else:
amount_to_add = residual_amount
2020-12-30 15:42:08 +01:00
all_money = float(cash_received) + self.store.get('paid_amount')
2020-07-22 06:26:51 +02:00
res = self.add_payment(amount_to_add, all_money, change)
if res.get('msg') == 'statement_closed':
self.dialog('statement_closed')
return False
2020-04-19 17:54:08 +02:00
if change < ZERO:
2020-12-30 15:42:08 +01:00
residual_amount = abs(change)
2020-04-19 17:54:08 +02:00
else:
2020-12-30 15:42:08 +01:00
residual_amount = ZERO
self.store.set({'residual_amount': residual_amount})
2020-04-19 17:54:08 +02:00
self.set_amount_received(all_money)
2020-07-22 06:26:51 +02:00
2020-12-30 15:42:08 +01:00
if residual_amount <= 0:
2020-04-19 17:54:08 +02:00
self._done_sale()
return True
2020-12-31 02:21:43 +01:00
for j in self._journals:
if j['id'] == self.default_journal['id']:
self.journal = j
2020-04-19 17:54:08 +02:00
if res['msg'] == 'missing_money':
self.message_bar.set('enter_payment', self.default_journal['name'])
return False
if change < ZERO:
self.message_bar.set('enter_payment', self.default_journal['name'])
2020-12-30 15:42:08 +01:00
residual_amount = res['residual_amount']
self.store.set({
'residual_amount': residual_amount,
'change': change,
2020-04-19 17:54:08 +02:00
})
2020-12-30 15:42:08 +01:00
if residual_amount <= 0:
2020-04-19 17:54:08 +02:00
self._done_sale()
return True
def validate_done_sale(self):
if self.model_sale_lines.rowCount() == 0:
self.dialog('sale_without_products')
self.set_state('add')
self.message_bar.set('system_ready')
return
return True
def _get_total_amount(self):
return self.model_sale_lines.get_sum('amount_w_tax')
def set_discount_amount(self):
res = 0
2020-12-30 15:42:08 +01:00
if self.store.sale_id:
2020-12-20 12:14:56 +01:00
res = self.Sale.get_discount_total({
2020-12-30 15:42:08 +01:00
'sale_id': self.store.sale_id
2020-04-19 17:54:08 +02:00
})
2020-12-30 15:42:08 +01:00
self.store.set({'discount': res})
2020-04-19 17:54:08 +02:00
def amount_text_changed(self, text=None):
if text:
self._amount_text += text
self.field_amount.setText(self._amount_text)
def input_text_changed(self, text=None):
if text:
self._input_text += text
elif text == '':
self._input_text = ''
self.label_input.setText(self._input_text)
def __do_invoice_thread(self):
2020-04-25 00:30:54 +02:00
try:
2020-12-20 12:14:56 +01:00
res = self.Sale.faster_post_invoice({
2020-12-30 15:42:08 +01:00
'sale_id': self.sale_to_post_id
2020-04-25 00:30:54 +02:00
})
except:
self.dialog('invoice_done_failed')
return
if not res['result']:
self.dialog('send_electronic_failed')
return
2020-12-30 15:42:08 +01:00
if self.store.get('is_credit'):
2020-04-19 17:54:08 +02:00
return
2020-12-30 15:42:08 +01:00
self.Sale.reconcile_invoice({'sale_id': self.sale_to_post_id})
2020-04-19 17:54:08 +02:00
def _done_sale(self, is_credit=False):
2020-12-30 15:42:08 +01:00
self.store.set({'is_credit': is_credit})
# We need create this temp variable called sale_to_post_id for this
# thread, because self.store.sale_id is deleted inmediately,
# so post invoice and reconcile it will fail if reference to sale_id
# is missing or None
self.sale_to_post_id = self.store.sale_id
table_assigned = self.store.get('table_assigned')
if table_assigned:
2020-12-20 12:14:56 +01:00
self.RestTables.write(
2020-12-30 15:42:08 +01:00
[table_assigned['id']], {
2020-12-20 22:52:28 +01:00
'state': 'available',
'sale': None,
}
2020-12-20 12:14:56 +01:00
)
2020-12-20 22:52:28 +01:00
self.do_invoice.start()
2020-12-20 12:14:56 +01:00
try:
2020-04-19 17:54:08 +02:00
if self.print_receipt == 'automatic':
2020-06-26 17:44:00 +02:00
_copies = self.device['shop']['invoice_copies']
2020-04-19 17:54:08 +02:00
if not is_credit:
2020-12-22 15:37:20 +01:00
self.print_invoice(copies=_copies, open_box=True)
2020-04-19 17:54:08 +02:00
if self.print_order and self.print_auto_order:
self.action_print_order()
2020-12-20 12:14:56 +01:00
except:
2020-04-19 17:54:08 +02:00
logging.error(sys.exc_info()[0])
2020-12-30 01:02:54 +01:00
# if not is_credit and self._commission_activated:
# agent_id = self.field_agent_ask.get_id()
# if self.auto_print_commission and agent_id:
# self.print_equivalent_invoice(self._sale['id'])
2020-04-19 17:54:08 +02:00
2020-12-23 18:24:47 +01:00
self.change_view_to('start_front')
if self.sale_automatic and self.type_pos_user not in ('cashier', 'order'):
2020-12-23 14:04:57 +01:00
self.create_new_sale()
2020-12-23 18:24:47 +01:00
2020-12-26 22:09:28 +01:00
# self.state_disabled()
2020-09-09 21:22:35 +02:00
self.message_bar.set('system_ready')
2020-04-19 17:54:08 +02:00
return True
2020-12-22 15:37:20 +01:00
def print_invoice(self, sale_id=None, type_doc='invoice', open_box=False, copies=1):
2020-04-19 17:54:08 +02:00
if not sale_id:
2020-12-30 15:42:08 +01:00
sale_id = self.store.sale_id
2020-12-21 17:03:44 +01:00
args = {
'sale_id': sale_id,
'type_doc': type_doc,
}
2020-12-20 12:14:56 +01:00
data = self.Sale.get_data(args)
2020-04-19 17:54:08 +02:00
for i in range(copies):
2020-12-22 15:37:20 +01:00
self.receipt_sale.print_sale(data, type_doc, open_box)
2020-04-19 17:54:08 +02:00
2020-09-17 04:41:10 +02:00
def button_duplicate_sale(self):
if self.sale_customer_selected:
2020-12-20 12:14:56 +01:00
res = self.Sale.duplicate_sale({
2020-09-17 04:41:10 +02:00
'sale_id': self.sale_customer_selected,
})
self.load_sale(res['sale_id'])
self.dialog_search_consumer.close()
self.dialog_table_sale_consumer.close()
self.dialog_sale_consumer_selected.close()
def button_create_delivery_party(self):
self.clear_delivery_party()
self.dialog_delivery_party_selected.show()
def button_sale_consumer_history(self):
if self._consumer:
delta = str(datetime.now() - timedelta(180))
dom = [
('create_date', '>=', delta),
('state', 'in', ['processing', 'done']),
('consumer', '=', self._consumer['id']),
]
self.model_sale_consumer.reset()
2020-12-20 12:14:56 +01:00
sales = self.Sale.find(dom, limit=10)
2020-09-17 04:41:10 +02:00
for record in sales:
self.model_sale_consumer.add_record(record)
self.dialog_table_sale_consumer.exec_()
2020-04-19 17:54:08 +02:00
def button_accept_pressed(self):
2020-12-27 01:50:38 +01:00
if not self._check_quantity() or not self._sale.get('id'):
2020-07-27 06:17:17 +02:00
return
2020-04-19 17:54:08 +02:00
if not self._sale['id'] or not self.model_sale_lines.rowCount() > 0:
return
self.set_state('accept')
def button_cash_pressed(self):
if not self.check_salesman():
return
if not self.validate_payment_term():
return
sale_id = self._sale['id']
2020-12-20 12:14:56 +01:00
res, msg = self.Sale.faster_process({'sale_id': sale_id})
2020-04-19 17:54:08 +02:00
if msg:
self.message_bar.set(msg)
return
self.set_amounts(res)
2020-12-22 15:37:20 +01:00
self._sale['number'] = res['number']
2020-12-29 20:32:42 +01:00
self.field_number.setText(self._sale['number'])
2020-04-19 17:54:08 +02:00
self.field_invoice.setText(res['invoice_number'])
2020-09-03 06:00:57 +02:00
self.field_amount.setText('')
2020-04-19 17:54:08 +02:00
if self.type_pos_user == 'salesman':
self.print_invoice(sale_id)
res = self._print_order(sale_id, 'delivery')
2020-12-23 18:24:47 +01:00
if self.sale_automatic:
self.create_new_sale()
2020-04-19 17:54:08 +02:00
return
2020-07-13 16:27:46 +02:00
if self.type_pos_user != 'cashier':
self.field_invoice_type.set_enabled(False)
2020-04-19 17:54:08 +02:00
self.message_bar.set('enter_payment', self.default_journal['name'])
2020-12-27 20:06:21 +01:00
self.set_state('payment')
2020-07-22 06:26:51 +02:00
self.label_input.setFocus()
2020-12-27 20:06:21 +01:00
self.table_sale_lines.setDisabled(True)
if self.enviroment == 'restaurant':
self.menu_dash.setDisabled(True)
2020-04-19 17:54:08 +02:00
def action_reservations(self):
logging.info('Buscando reservas.....')
def action_tables(self):
2020-12-20 18:21:17 +01:00
self.manage_tables.open_tables()
2020-04-19 17:54:08 +02:00
self.dialog_manage_tables.exec_()
def action_tip(self):
2020-12-30 01:02:54 +01:00
if self._state in ['finished']:
return
2020-12-30 01:02:54 +01:00
value = self.field_tip_amount_ask.text()
if not value and self._config['tip_rate']:
2020-04-19 17:54:08 +02:00
total_amount = int(self._get_total_amount())
2020-12-30 01:02:54 +01:00
value = int((self._config['tip_rate'] / 100) * total_amount)
self.field_tip_amount_ask.setText(str(value))
else:
self.dialog_tip_amount.exec_()
value = self.field_tip_amount_ask.text()
value = int(value)
2020-12-30 15:42:08 +01:00
res = self.store.update({'tip_amount': value})
self.set_amounts(res)
2020-04-19 17:54:08 +02:00
2020-12-21 18:13:48 +01:00
def action_delivery(self):
2020-12-30 01:02:54 +01:00
if self._state in ['finished']:
2020-12-21 18:13:48 +01:00
return
2020-12-30 01:02:54 +01:00
self.dialog_delivery_amount.exec_()
value = self.field_delivery_amount_ask.text()
value = int(value)
2020-12-30 15:42:08 +01:00
res = self.store.update({'delivery_amount': value})
self.set_amounts(res)
2020-12-21 18:13:48 +01:00
2020-04-19 17:54:08 +02:00
def action_salesman(self):
if self._state in ['cash']:
return
2020-04-19 17:54:08 +02:00
self.dialog_salesman.exec_()
2020-12-29 20:32:42 +01:00
def action_delivery_party(self):
self.dialog_delivery_party.exec_()
2020-09-03 06:00:57 +02:00
2020-12-29 20:32:42 +01:00
def action_delivery_party_panel(self):
2020-09-15 04:53:44 +02:00
self.dialog_control_panel.close()
self.dialog_table_delivery_party.exec_()
2020-09-03 06:00:57 +02:00
def action_control_panel(self):
self.dialog_control_panel.exec_()
2020-09-17 17:20:21 +02:00
def clear_money_count_table(self):
2020-09-14 05:36:23 +02:00
new_data = [[d[0], 0, 0] for d in self.model_money_count._data]
self.model_money_count._data = new_data
2020-09-17 17:20:21 +02:00
def dialog_money_count_accepted(self):
2020-09-14 05:36:23 +02:00
return True
2020-09-03 06:00:57 +02:00
def action_open_statement(self):
2020-09-14 05:36:23 +02:00
if not self.dialog_money_count.exec_():
return
2020-12-20 12:14:56 +01:00
res = self.Sale.faster_open_statement({
2020-09-14 05:36:23 +02:00
'device': self.device['id'],
'total_money': Decimal(
self.row_field_total_money.text().replace(',', '')
2020-12-30 01:02:54 +01:00
),
2020-09-03 06:00:57 +02:00
})
2020-09-14 05:36:23 +02:00
if res['result']:
2020-09-03 06:00:57 +02:00
self.dialog('statement_created')
2020-09-14 05:36:23 +02:00
self.row_field_total_money.setText('0')
2020-09-17 17:20:21 +02:00
self.clear_money_count_table()
2020-09-03 06:00:57 +02:00
def action_closed_statement(self):
2020-09-14 05:36:23 +02:00
if not self.dialog_money_count.exec_():
return
2020-12-20 12:14:56 +01:00
res = self.Sale.faster_close_statement({
2020-09-14 05:36:23 +02:00
'device': self.device['id'],
'data': self.model_money_count._data,
2020-09-03 06:00:57 +02:00
})
2020-09-14 05:36:23 +02:00
if res['result']:
2020-09-03 06:00:57 +02:00
self.dialog('statement_finish')
2020-09-14 05:36:23 +02:00
self.row_field_total_money.setText('0')
2020-09-17 17:20:21 +02:00
self.clear_money_count_table()
2020-09-03 06:00:57 +02:00
def action_table_discount(self):
self.dialog_global_discount_table.exec_()
2020-09-03 06:00:57 +02:00
2020-04-19 17:54:08 +02:00
def action_tax(self):
self.dialog_tax.exec_()
2020-12-27 20:06:21 +01:00
def button_payment_pressed(self):
if self._state not in ('cash', 'payment'):
2020-04-19 17:54:08 +02:00
self.dialog('add_payment_sale_draft')
return
self.dialog_payment.exec_()
def _check_credit_capacity(self, party):
if party['credit_limit_amount']:
2020-07-27 06:17:17 +02:00
if (party['credit_limit_amount'] * Decimal(RATE_CREDIT_LIMIT)) < (
party['credit_amount'] + self._get_total_amount()):
2020-04-19 17:54:08 +02:00
self.dialog('credit_limit_capacity')
return True
def validate_payment_term(self):
2020-12-29 22:58:21 +01:00
payment_term = self.store.get('payment_term')
is_credit = payment_term.get('is_credit', None)
if not is_credit:
return True
2020-04-23 22:52:05 +02:00
party, = self.Party.find([('id', '=', self.party_id)])
2020-12-29 22:58:21 +01:00
if self._credit_limit_activated:
2020-04-19 17:54:08 +02:00
if self.party_id == self.default_party['id']:
self.dialog('customer_not_credit')
return False
2020-12-29 22:58:21 +01:00
elif not party['credit_limit_amount']:
2020-04-19 17:54:08 +02:00
self.dialog('customer_not_credit')
return False
2020-12-20 12:14:56 +01:00
self._credit_amount = self.Sale.get_credit_amount_party({'party_id': self.party_id})
2020-04-19 17:54:08 +02:00
self._credit_limit_amount = party['credit_limit_amount']
if is_credit and self._credit_limit_amount and \
self._credit_limit_amount < (self._credit_amount + self._get_total_amount()):
self.dialog('credit_limit_exceed')
return False
return True
def action_payment_term_selection_changed(self):
is_credit = self._payment_terms[str(self.field_payment_term_id)]['is_credit']
2020-12-20 12:14:56 +01:00
self.Sale.write([self._sale['id']], {'payment_term': self.field_payment_term_id})
2020-09-09 23:12:52 +02:00
self.field_payment_term.setText(self._payment_terms[str(self.field_payment_term_id)]['name'])
2020-09-09 23:22:34 +02:00
if is_credit and self.type_pos_user != 'salesman':
2020-04-19 17:54:08 +02:00
if self.validate_credit_limit():
self._done_sale(is_credit=True)
def validate_credit_limit(self):
if self._credit_limit_amount and self._credit_limit_amount < (self._credit_amount + self._get_total_amount()):
self.dialog('credit_limit_exceed')
return False
else:
return True
def action_delivery_charge_selection_changed(self, index):
val = self.field_delivery_charge.get_id()
if val:
2020-12-20 12:14:56 +01:00
self.Sale.write([self._sale['id']], {'delivery_charge': val})
2020-04-19 17:54:08 +02:00
2020-12-20 12:14:56 +01:00
def action_kind_selection_changed(self, index):
val = self.field_kind.get_id()
2020-12-29 20:32:42 +01:00
self.store.update({'kind': val})
2020-08-20 06:40:41 +02:00
2020-12-31 21:50:37 +01:00
def action_payment_method_selection_changed(self, index):
val = self.field_payment_method.get_id()
self.store.update({'payment_method': val})
2020-04-19 17:54:08 +02:00
def action_invoice_type_selection_changed(self, index):
val = self.field_invoice_type.get_id()
2020-11-07 18:29:25 +01:00
if val and self._sale and self._sale.get('id'):
2020-12-20 12:14:56 +01:00
self.Sale.write([self._sale['id']], {'invoice_type': val})
2020-04-19 17:54:08 +02:00
def action_tax_selection_changed(self):
2020-12-20 12:14:56 +01:00
res = self.Sale.add_tax(self._sale['id'], self.field_tax_id,
self._context)
2020-12-30 15:42:08 +01:00
self.set_amounts(res)
2020-04-19 17:54:08 +02:00
2020-07-22 06:26:51 +02:00
def action_consumer(self):
2020-12-21 17:03:44 +01:00
if not self._consumer.get('id'):
self.clear_dialog_consumer()
else:
self.set_consumer()
2020-07-22 06:26:51 +02:00
self.dialog_search_consumer.show()
self.row_field_phone.setFocus()
2020-04-19 17:54:08 +02:00
def action_print_sale(self):
number = self.field_invoice.text()
if not number:
2020-12-29 20:32:42 +01:00
number = self.field_number.text()
2020-04-19 17:54:08 +02:00
if number:
self.field_invoice_number_ask.setText(number)
res = self.dialog_print_invoice.exec_()
if res == DIALOG_REPLY_NO:
return
number = self.field_invoice_number_ask.text()
printer_id = self.field_printer_ask.get_id()
type_doc = self.field_type_ask.get_id()
2020-12-21 17:03:44 +01:00
sale_id = None
2020-04-19 17:54:08 +02:00
if number:
2020-09-19 17:13:08 +02:00
if type_doc in ['order', 'delivery']:
2020-12-27 17:30:02 +01:00
if number == self._sale.get('number'):
2020-12-21 17:03:44 +01:00
sale_id = self._sale['id']
else:
sales = self.Sale.find([('number', '=', number)])
if sales:
sale_id = sales[0]['id']
2020-04-19 17:54:08 +02:00
else:
2020-12-20 23:29:07 +01:00
args = {'number': number}
sale = self.Sale.get_sale_from_invoice(args)
2020-12-22 14:55:00 +01:00
if sale:
sale_id = sale['id']
2020-04-19 17:54:08 +02:00
else:
sale_id = self._sale['id']
2020-12-21 17:03:44 +01:00
if not sale_id:
return self.message_bar.set('sale_number_not_found')
2020-04-19 17:54:08 +02:00
if printer_id == '1':
2020-12-21 17:03:44 +01:00
self.print_invoice(sale_id, type_doc=type_doc)
2020-04-19 17:54:08 +02:00
else:
self.print_odt_invoice(sale)
def print_odt_invoice(self, sale):
if not sale.get('invoices'):
return
invoice_id = sale['invoices'][0]
model = u'account.invoice'
data = {
'model': model,
'action_id': self._action_report['id'],
'id': invoice_id,
'ids': [invoice_id],
}
ctx = {'date_format': u'%d/%m/%Y'}
ctx.update(self._context)
2020-07-27 06:17:17 +02:00
Action.exec_report(self.conn, u'account.invoice', data, direct_print=True, context=ctx)
2020-04-19 17:54:08 +02:00
def action_comment(self):
self.dialog_comment.exec_()
2020-12-29 20:32:42 +01:00
comment = self.field_comment.toPlainText()
2020-04-19 17:54:08 +02:00
if comment:
2020-12-20 12:14:56 +01:00
self.Sale.write([self._sale['id']], {'comment': comment})
2020-04-19 17:54:08 +02:00
def action_position(self):
self.dialog_position.exec_()
2020-12-29 20:32:42 +01:00
position = self.field_position.text()
self.store.update({'position': position})
2020-04-19 17:54:08 +02:00
def action_agent(self):
self.dialog_agent.exec_()
res = self.field_commission_ask.text()
if not res:
return
commission = float(res)
2020-12-20 12:14:56 +01:00
sale, = self.Sale.find([
2020-04-19 17:54:08 +02:00
('id', '=', self._sale['id']),
])
self.field_agent_id = self.field_agent_ask.get_id()
if self.field_agent_id and commission:
agent, = self.Agent.find([
2020-04-19 17:54:08 +02:00
('id', '=', self.field_agent_id),
])
if commission <= agent['plan']['percentage']:
2020-12-20 12:14:56 +01:00
self.Sale.write([self._sale['id']], {
2020-04-19 17:54:08 +02:00
'agent': self.field_agent_id,
'commission': int(commission),
})
else:
self.message_bar.set('invalid_commission')
return
self.message_bar.set('system_ready')
comm_string = str('[' + str(commission) + ']' + ' ') + (str(self.field_agent_ask.text()))
self.field_agent.setText(comm_string)
self._set_commission_amount(sale['untaxed_amount'], commission)
def _set_commission_amount(self, untaxed_amount, commission):
untaxed_amount = int(untaxed_amount)
commission = int(commission)
total = ((untaxed_amount * commission) / 100)
self.field_commission_amount.setText(str(total))
def action_party(self):
2020-07-29 20:35:05 +02:00
if self._state in ['cash']:
return
2020-04-19 17:54:08 +02:00
self.dialog_search_parties.clear_rows()
self.dialog_search_parties.execute()
def action_global_discount(self, sale_id=None):
if self._state in ['accept', 'cash']:
return
2020-04-19 17:54:08 +02:00
self.dialog_global_discount.exec_()
discount = self.field_global_discount_ask.text()
if discount and discount.isdigit():
self.validate_discount(discount)
2020-12-31 00:12:12 +01:00
def validate_discount(self, record):
if self.model_sale_lines.rowCount() > 0:
lines = [line['id'] for line in self.model_sale_lines._data]
2020-12-31 00:12:12 +01:00
res = self.set_discount(int(record['discount']), lines)
if not res:
self.message_bar.set('discount_not_valid')
return False
2020-04-19 17:54:08 +02:00
def _print_order(self, sale_id, kind, reversion=False):
result = False
2020-12-20 12:14:56 +01:00
try:
2020-12-20 04:30:50 +01:00
args = {
'sale_id': sale_id,
'reversion': reversion,
'repeat': False,
}
2020-12-22 15:37:20 +01:00
orders, sale_number = self.Sale.get_order2print(args)
self._sale['number'] = sale_number
2020-12-29 20:32:42 +01:00
self.field_number.setText(self._sale['number'])
2020-04-19 17:54:08 +02:00
result = self.receipt_order.print_orders(orders, reversion, kind)
2020-12-20 12:14:56 +01:00
except:
2020-04-19 17:54:08 +02:00
logging.error('Printing order fail!')
return result
def action_print_order(self, sale_id=None, reversion=False):
res = self.dialog_order.exec_()
if res == DIALOG_REPLY_NO:
return
2020-04-21 04:13:03 +02:00
2020-12-20 04:30:50 +01:00
kind = 'dispatch'
2020-04-19 17:54:08 +02:00
if self.enviroment == 'restaurant':
kind = 'command'
if not self.print_order:
return
if not sale_id and self._sale['id']:
sale_id = self._sale['id']
result = self._print_order(sale_id, kind)
if result:
# Show dialog if send sale order was successful
self.dialog('order_successfully')
else:
self.dialog('order_failed')
2020-12-28 01:56:10 +01:00
if self.enviroment == 'restaurant':
self.change_view_to('start_front')
2020-04-19 17:54:08 +02:00
def action_channel(self):
if self._state != 'cash':
self.dialog_channel.exec_()
2020-04-19 17:54:08 +02:00
def action_payment_term(self):
if self._state == 'cash' or self.type_pos_user == 'salesman':
self.dialog_payment_term.exec_()
def action_new_sale(self):
2020-07-29 20:35:05 +02:00
if self._state in ['cash']:
return
2020-04-19 17:54:08 +02:00
if not self._sale['id']:
return
if self._ask_new_sale():
2020-12-23 14:04:57 +01:00
self.create_new_sale()
2020-04-19 17:54:08 +02:00
def numpad_price_clicked(self):
code = self.label_input.text()
product = self._search_product(code)
if not product:
return
def _ask_new_sale(self):
dialog = self.dialog('new_sale', response=True)
res = dialog.exec_()
if res == DIALOG_REPLY_NO:
return False
return True
def action_cancel(self):
2020-09-16 01:23:40 +02:00
if self._state == 'disabled':
2020-08-05 19:20:33 +02:00
return
2020-04-19 17:54:08 +02:00
if self.type_pos_user == 'cashier':
self.dialog_cancel_invoice.exec_()
password = self.field_password_for_cancel_ask.text()
if password != self._password_admin:
return self.dialog('not_permission_for_cancel')
if not self._sale['id']:
return
2020-12-27 20:06:21 +01:00
if self._state in ('cash', 'payment') and not self.user_can_delete:
2020-04-19 17:54:08 +02:00
return self.dialog('not_permission_delete_sale')
if self.type_pos_user in ('order', 'salesman') and \
self._sale.get('invoice_number'):
return self.dialog('not_permission_delete_sale')
dialog = self.dialog('cancel_sale', response=True)
response = dialog.exec_()
if response == DIALOG_REPLY_NO:
return
2020-12-20 12:14:56 +01:00
self.Sale.cancel_sale(self._sale['id'])
2020-04-19 17:54:08 +02:00
self.field_password_for_cancel_ask.setText('')
self.set_state('cancel')
self.clear_right_panel()
2020-12-23 18:24:47 +01:00
if self.sale_automatic:
self.create_new_sale()
2020-04-19 17:54:08 +02:00
def action_search_product(self):
if self._state == 'cash':
return
self.dialog_search_products.show()
2020-12-23 18:24:47 +01:00
def action_start_delivery(self):
2020-12-31 02:21:43 +01:00
# self.store.clear()
2020-12-23 18:24:47 +01:00
self.create_new_sale(kind='delivery')
2020-12-23 19:08:37 +01:00
def action_start_table(self):
2020-12-31 02:21:43 +01:00
# self.store.clear()
2020-12-23 19:08:37 +01:00
self.create_new_sale(kind='to_table')
def action_start_take_away(self):
2020-12-31 02:21:43 +01:00
# self.store.clear()
2020-12-23 19:08:37 +01:00
self.create_new_sale(kind='take_away')
2020-12-23 18:24:47 +01:00
2020-04-19 17:54:08 +02:00
def action_search_sale(self):
2020-12-15 06:08:16 +01:00
delta = str(datetime.now() - timedelta(2))
2020-04-19 17:54:08 +02:00
if self.type_pos_user == 'cashier':
dom = ['OR', [
('create_date', '>=', delta),
('state', 'in', ['quotation', 'confirmed']),
], [
('state', '=', 'processing'),
('invoice.state', '=', 'draft'),
('invoice.type', '=', 'out'),
]]
elif self.type_pos_user in ('order', 'salesman'):
dom = [
('state', '=', 'draft'),
('create_date', '>=', delta),
]
else:
dom = [
('state', 'in', ['draft', 'quotation', 'confirmed']),
('create_date', '>=', delta),
]
2020-12-15 06:04:21 +01:00
fields = self.dialog_search_sales.fields_names
2020-12-20 12:14:56 +01:00
sales = self.Sale.find(dom, fields=fields, order=[('id', 'DESC')])
2020-04-19 17:54:08 +02:00
self.dialog_search_sales.set_from_values(sales)
if self.enviroment == 'retail':
dom_draft = [
('create_date', '>=', delta),
('state', '=', 'draft'),
('invoice_number', '!=', None),
]
2020-12-20 12:14:56 +01:00
sales_draft = self.Sale.find(dom_draft)
2020-04-19 17:54:08 +02:00
self.dialog_search_sales.set_counter_control(sales_draft)
response = self.dialog_search_sales.execute()
self.field_invoice_type.set_enabled(True)
2020-04-19 17:54:08 +02:00
if response == DIALOG_REPLY_NO:
return
def on_selected_sale(self):
sale_id = self.dialog_search_sales.get_id()
if not sale_id:
return
self.load_sale(sale_id)
self.setFocus()
self.label_input.setFocus()
2020-12-23 19:08:37 +01:00
self.change_view_to('order_front')
2020-04-19 17:54:08 +02:00
2020-08-20 06:40:41 +02:00
def on_selected_party(self, party_id=None):
if not party_id:
party_id = self.dialog_search_parties.get_id()
2020-04-19 17:54:08 +02:00
if not party_id:
return
2020-04-22 02:26:19 +02:00
party, = self.Party.find([('id', '=', party_id)])
2020-12-30 15:42:08 +01:00
address_id = ''
if party['addresses']:
address_id = party['addresses'][0]['id']
2020-04-19 17:54:08 +02:00
values = {
2020-12-30 15:42:08 +01:00
'party': {'id': party_id, 'name': party['name']},
'invoice_address': address_id,
'shipment_address': address_id,
2020-04-19 17:54:08 +02:00
}
2020-06-19 17:28:55 +02:00
payment_term = party.get('customer_payment_term')
if payment_term:
2020-12-30 15:42:08 +01:00
values['payment_term'] = payment_term
2020-04-19 17:54:08 +02:00
2020-04-22 02:26:19 +02:00
if party.get('salesman'):
2020-12-30 15:42:08 +01:00
values.update({'salesman': party.get('salesman')})
2020-12-30 01:02:54 +01:00
self.store.update(values)
self.party_id = party_id
2020-04-19 17:54:08 +02:00
# if self._credit_limit_activated:
# self._check_credit_capacity(party)
self.message_bar.set('system_ready')
self.setFocus()
self.label_input.setFocus()
def load_sale(self, sale_id):
# loads only draft sales
self.clear_data()
self.clear_left_panel()
self.clear_right_panel()
2020-12-29 20:32:42 +01:00
self.store.clear()
2020-12-20 12:14:56 +01:00
sale, = self.Sale.find([('id', '=', sale_id)])
2020-12-29 20:32:42 +01:00
self.store.set_sale(sale['id'])
self.store.set(sale)
2020-04-19 17:54:08 +02:00
self._sale.update(sale)
self.table_payment_lines.reset()
self._set_sale_date()
2021-01-02 18:38:24 +01:00
self.journal = {}
2020-04-19 17:54:08 +02:00
if self.field_delivery_charge:
self.field_delivery_charge.set_enabled(True)
if sale.get('delivery_charge'):
self.field_delivery_charge.set_from_id(sale['delivery_charge'])
2020-12-21 17:03:44 +01:00
2020-04-19 17:54:08 +02:00
if sale.get('table_assigned'):
2020-12-20 17:05:04 +01:00
self.field_table_assigned.setText(sale['table_assigned']['name'] or '')
2020-04-19 17:54:08 +02:00
2020-12-21 17:03:44 +01:00
consumer = sale.get('consumer', None)
if consumer:
self.field_consumer.setText(consumer['name'] or '')
self._consumer, = self.Consumer.find([
('id', '=', consumer['id']),
])
2020-04-19 17:54:08 +02:00
self.field_change.zero()
if self._commission_activated:
2020-04-23 22:52:05 +02:00
if hasattr(self, 'field_agent') and sale.get('agent') \
2020-04-19 17:54:08 +02:00
and sale.get('commission'):
commission = sale.get('commission')
2020-04-23 22:52:05 +02:00
self.field_agent.setText('[' + str(int(commission)) + ']' + ' ' + sale['agent']['name'])
self.field_agent_id = sale['agent']['id']
self.field_agent_ask.setText(sale['agent']['name'])
2020-04-19 17:54:08 +02:00
self.field_commission_ask.setText(str(commission))
self._set_commission_amount(sale['untaxed_amount'], commission)
2020-04-23 22:52:05 +02:00
self.line_ids = [l['id'] for l in sale.get('lines')]
2020-04-19 17:54:08 +02:00
if sale.get('lines'):
2020-12-20 12:14:56 +01:00
lines = self.SaleLine.find([
2020-04-23 22:52:05 +02:00
('id', 'in', self.line_ids),
2020-04-19 17:54:08 +02:00
])
sale['lines'] = lines
for line in lines:
self.add_sale_line(line)
if sale.get('payments'):
for payment in sale['payments']:
self.table_payment_lines.record_add(payment)
self.set_state('add')
2020-04-23 22:52:05 +02:00
self.party_id = sale['party']['id']
2020-04-19 17:54:08 +02:00
self.set_amounts(sale)
self.set_amount_received()
2020-09-03 06:00:57 +02:00
self.field_amount.setText('')
2020-12-28 23:39:10 +01:00
self.message_bar.set('system_ready')
2020-04-19 17:54:08 +02:00
if self.type_pos_user in ('cashier', 'order', 'salesman'):
self.table_sale_lines.setEnabled(True)
2020-12-27 20:06:21 +01:00
if self.enviroment == 'restaurant':
2020-12-28 23:39:10 +01:00
self.table_sale_lines.setEnabled(True)
2020-12-27 20:06:21 +01:00
self.menu_dash.setDisabled(False)
2020-04-19 17:54:08 +02:00
def set_change_amount(self):
amount_paid = self.table_payment_lines.get_sum('amount')
res = amount_paid - self._get_total_amount()
self.field_change.setText(res)
def set_amount_received(self, cash_received=ZERO):
2020-12-30 15:42:08 +01:00
pass
2020-04-19 17:54:08 +02:00
def set_amounts(self, res=None):
if not res:
2020-12-20 12:14:56 +01:00
res = self.Sale.get_amounts({'sale_id': self._sale['id']})
2020-12-30 15:42:08 +01:00
self.store.set(res)
# self.set_discount_amount()
2020-04-19 17:54:08 +02:00
def _get_products_by_category(self, cat_id):
records = self.Product.find([
('code', '!=', None),
('template.salable', '=', True),
('template.categories', '=', cat_id),
])
2020-12-29 22:58:21 +01:00
return records
2020-04-19 17:54:08 +02:00
def get_product_by_categories(self):
2020-12-28 23:39:10 +01:00
self.allow_categories = [
pc for pc in self.product_categories if not pc['parent'] and not pc['accounting']
]
2020-04-19 17:54:08 +02:00
for cat in self.allow_categories:
cat['icon'] = get_icon(cat['name_icon'])
2020-12-29 00:17:37 +01:00
if cat.get('childs'):
for child in cat.get('childs'):
child['items'] = self._get_products_by_category(child['id'])
else:
cat['items'] = self._get_products_by_category(cat['id'])
2020-04-19 17:54:08 +02:00
return self.allow_categories
2020-09-03 06:00:57 +02:00
def get_menu_control_panel(self):
menu_dash = [
['button_open', self.tr('OPEN STATEMENTS'), 'action_open_statement'],
['button_closed', self.tr('CLOSED STATEMENTS'), 'action_closed_statement'],
2020-09-14 05:36:23 +02:00
# ['button_money', self.tr('COUNT MONEY'), 'action_count_money'],
2020-09-03 06:00:57 +02:00
['button_discount', self.tr('GLOBAL DISCOUNT'), 'action_table_discount'],
2020-12-29 20:32:42 +01:00
['button_delivery_party', self.tr('DELIVERY MEN'), 'action_delivery_party_panel'],
2020-09-03 06:00:57 +02:00
['button_help', self.tr('HELP'), 'action_help'],
]
return menu_dash
2020-04-19 17:54:08 +02:00
def _get_childs(self, parent_cat):
res = {}
for cat_id in parent_cat['childs']:
sub_categories = self.Category.find([
('parent', '=', parent_cat['id'])
])
for sub_cat in sub_categories:
res.update(self._get_childs(sub_cat))
res = {
'id': parent_cat['id'],
'name': parent_cat['name'],
'childs': parent_cat['childs'],
'records': [],
'obj': parent_cat,
}
return res
def get_category_items(self, records):
records_by_category = {}
def _get_tree_categories(cat):
sub_categories = {}
if not cat['childs']:
sub_categories[cat['name']] = records_by_category.get(cat['id']) or []
else:
for child in cat['childs']:
sub_categories.update(_get_tree_categories(
self.target_categories[child]['obj']))
return sub_categories
for record in records:
cat_id = record.get('template.account_category')
if cat_id not in records_by_category.keys():
records_by_category[cat_id] = []
records_by_category[cat_id].append(record)
res = {}
for ac in self.allow_categories:
res[ac['name']] = _get_tree_categories(ac)
return res
def on_selected_product(self):
if self.dialog_search_products.current_row:
self._current_line_id = None
self.clear_right_panel()
2020-12-29 22:58:21 +01:00
self.add_product(record=self.dialog_search_products.current_row)
2020-04-19 17:54:08 +02:00
def on_selected_icon_product(self):
if self.dialog_search_products.current_row:
code = self.dialog_search_products.current_row['code']
products = self.Product.find([
('code', '=', code)
])
if not products:
return
product = products[0]
2020-12-30 01:02:54 +01:00
# image = Image(name='product_icon')
# if not product['image']:
# return
#
# b64image = product['image'].encode()
# image.set_image(b64image, kind='bytes')
# image.activate()
2020-04-19 17:54:08 +02:00
def on_selected_stock_product(self):
if self.dialog_search_products.current_row:
code = self.dialog_search_products.current_row['code']
res = self.Product.get_stock_by_locations({'code': code})
self.dialog_product_stock.update_values(res)
self.dialog_product_stock.show()
2020-12-30 22:04:23 +01:00
def on_selected_item_mix(self, record):
2020-12-31 00:12:12 +01:00
list_price = self._current_line['product'].get('list_price')
if list_price < record['list_price']:
# Update price in selected_line
self.set_unit_price(record['template']['sale_price_w_tax'])
list_price = None
self.on_selected_item(record, list_price)
def on_selected_item(self, record, list_price=None):
2020-12-29 22:58:21 +01:00
if record:
2020-04-19 17:54:08 +02:00
self.clear_right_panel()
2020-12-31 00:12:12 +01:00
self.add_product(record=record, list_price=list_price)
def on_selected_salesman(self, salesman):
if salesman:
2020-12-31 02:21:43 +01:00
salesman_data = {
'id': salesman['id'],
'name': salesman['rec_name'],
}
self.store.update({'salesman': salesman_data})
2020-09-09 21:22:35 +02:00
self.dialog_salesman.close()
2020-09-03 06:00:57 +02:00
def on_selected_discount(self, discount):
if discount:
self.validate_discount(discount)
self.dialog_global_discount_table.close()
self.dialog_control_panel.close()
2020-12-29 20:32:42 +01:00
def on_selected_delivery_party(self, delivery_party_id):
if delivery_party_id:
self.store.update({'delivery_party': delivery_party_id})
self.dialog_delivery_party.close()
2020-09-03 06:00:57 +02:00
def on_selected_payment_term(self, payterm_id):
if payterm_id:
self.field_payment_term_id = payterm_id
self.action_payment_term_selection_changed()
2020-09-09 21:22:35 +02:00
self.dialog_payment_term.close()
2020-09-03 06:00:57 +02:00
2020-12-29 22:58:21 +01:00
def on_selected_channel(self, channel):
2020-12-30 01:02:54 +01:00
self.store.update({'channel': channel})
self.dialog_channel.close()
2020-12-31 02:21:43 +01:00
def on_selected_payment(self, journal):
self.journal = journal
if journal.get('id'):
self.field_journal_id = journal['id']
2020-09-03 06:00:57 +02:00
self.dialog_payment.close()
2020-12-31 02:21:43 +01:00
self.message_bar.set('enter_payment', journal['rec_name'])
2020-09-03 06:00:57 +02:00
2020-04-19 17:54:08 +02:00
def on_search_product(self):
target = self.dialog_search_products.filter_field.text()
if not target:
return
target_words = target.split(' ')
2020-04-29 15:36:14 +02:00
domain = [
2020-08-20 06:40:41 +02:00
('template.active', '=', True),
('active', '=', True),
('template.salable', '=', True),
]
2020-04-19 17:54:08 +02:00
for tw in target_words:
if len(tw) <= 1:
continue
2020-11-06 21:02:01 +01:00
clause = [
'OR',
('template.name', 'ilike', '%{:}%'.format(tw)),
('description', 'ilike', '%{:}%'.format(tw)),
('code', 'ilike', '%{:}%'.format(tw))
]
2020-04-19 17:54:08 +02:00
domain.append(clause)
2020-12-15 06:04:21 +01:00
2020-08-20 06:40:41 +02:00
if not self._sale_pos_restaurant and self.shop.get('product_categories'):
categories_id = [ct['id'] for ct in self.shop['product_categories']]
2020-11-06 21:02:01 +01:00
domain.append(('template.categories', 'in', categories_id))
2020-04-19 17:54:08 +02:00
if not domain:
return
2020-11-06 21:02:01 +01:00
2020-04-19 17:54:08 +02:00
if self.cache_local:
2020-09-07 04:19:19 +02:00
domain = [clause]
2020-12-29 20:32:42 +01:00
products = self.local_db.find_product_elastic(domain, limit=100)
2020-04-19 17:54:08 +02:00
else:
2020-12-15 06:04:21 +01:00
fields = self.dialog_search_products.fields_names
products = self.Product.find(domain, fields=fields,
limit=100, ctx=self.stock_context)
2020-11-06 21:02:01 +01:00
2020-04-19 17:54:08 +02:00
self.dialog_search_products.set_from_values(products)
def on_search_party(self):
target = self.dialog_search_parties.filter_field.text()
if not target:
return
target_words = target.split(' ')
domain = [('id_number', '!=', None)]
for tw in target_words:
if len(tw) <= 2:
continue
2020-12-23 14:04:57 +01:00
or_clause = [
'OR',
('name', 'ilike', '%' + tw + '%'),
('contact_mechanisms.value', 'like', tw + '%'),
('id_number', 'like', tw + '%')
]
2020-04-19 17:54:08 +02:00
domain.append(or_clause)
2020-12-15 06:04:21 +01:00
fields_names = self.dialog_search_parties.fields_names
parties = self.Party.find(domain, fields=fields_names)
2020-04-19 17:54:08 +02:00
self.dialog_search_parties.set_from_values(parties)
def clear_data(self):
2020-12-24 00:53:28 +01:00
self._sale = {'total_amount': 0, 'tip_amount': 0, 'delivery_amount': 0}
2020-04-19 17:54:08 +02:00
self.party_name = None
self._sale_line = {'id': None}
self._total_amount = {}
self._sale_lines_taxes = {}
self.field_journal_id = self.default_journal['id']
2020-12-29 22:58:21 +01:00
self.field_voucher_ask.setText('')
2020-04-19 17:54:08 +02:00
def clear_left_panel(self):
self.field_party.setText('')
self.field_salesman.setText('')
self.field_salesman_id = None
2020-12-10 05:11:52 +01:00
self.field_invoice_type.set_from_id('P')
2020-04-19 17:54:08 +02:00
self.field_party_id = None
self.field_agent_id = None
self.field_payment_term_id = self.default_payment_term['id']
self.field_payment_term.setText(self.default_payment_term['name'])
2020-12-29 20:32:42 +01:00
self.field_sale_date.setText('')
2020-04-19 17:54:08 +02:00
self.field_global_discount_ask.setText('')
2020-09-03 06:00:57 +02:00
self.field_amount.setText('')
2020-12-29 20:32:42 +01:00
self.field_number.setText('')
self.field_state.setText('')
2020-04-19 17:54:08 +02:00
self.current_comment = ''
2020-12-21 17:03:44 +01:00
if hasattr(self, 'field_consumer'):
self.field_consumer.setText('')
2020-04-19 17:54:08 +02:00
if self.field_delivery_charge:
self.field_delivery_charge.set_from_id('')
if self.field_table_assigned:
self.field_table_assigned.setText('')
2020-12-29 20:32:42 +01:00
if hasattr(self, 'field_comment'):
self.field_comment.document().clear()
2020-04-19 17:54:08 +02:00
if self._commission_activated and hasattr(self, 'field_agent'):
self.field_agent.setText('')
self.field_agent_ask.setText('')
self.field_commission_ask.setText('')
self.field_commission_amount.setText('')
self.model_sale_lines.reset()
self.clear_input_text()
self.clear_amount_text()
def clear_right_panel(self):
self.field_invoice.setText('')
2020-12-24 00:53:28 +01:00
self.field_tip_amount.setText('')
self.field_delivery_amount.setText('')
2020-04-19 17:54:08 +02:00
self.field_untaxed_amount.zero()
2020-12-24 16:19:59 +01:00
self.field_net_amount.zero()
2020-04-19 17:54:08 +02:00
self.field_taxes_amount.zero()
self.field_total_amount.zero()
self.field_change.zero()
2020-12-30 15:42:08 +01:00
self.field_paid_amount.zero()
2020-04-19 17:54:08 +02:00
self.field_discount.zero()
2020-12-30 15:42:08 +01:00
self.field_residual_amount.zero()
2020-04-19 17:54:08 +02:00
self.table_payment_lines.reset()
def state_enabled(self):
pass
def state_disabled(self):
self.payment_ctx = {}
self.clear_left_panel()
self.table_sale_lines.setDisabled(True)
self.set_state('disabled')
if self.field_delivery_charge:
self.field_delivery_charge.set_enabled(False)
2020-12-23 14:04:57 +01:00
def create_new_sale(self, kind=None):
2020-07-27 06:17:17 +02:00
if self.enviroment == 'restaurant' and self._sale_pos_restaurant:
2020-08-20 06:40:41 +02:00
self.clear_dialog_consumer()
2020-12-23 19:08:37 +01:00
# self.check_empty_sale()
2020-04-19 17:54:08 +02:00
if self.type_pos_user == 'cashier':
2020-07-28 23:54:15 +02:00
self.message_bar.set('not_sale')
2020-12-26 22:09:28 +01:00
# self.state_disabled()
2020-04-19 17:54:08 +02:00
return
2020-12-29 20:32:42 +01:00
self.store.clear()
2020-12-31 02:21:43 +01:00
self.journal = {}
2020-04-19 17:54:08 +02:00
self.set_state('add')
self.input_text_changed('')
self.amount_text_changed('0')
self.clear_sign()
2020-12-28 00:19:15 +01:00
self.show_right_panel(True)
2020-08-20 06:40:41 +02:00
self.consumer_id = None
2020-04-19 17:54:08 +02:00
self.payment_ctx = {}
self.table_sale_lines.setEnabled(True)
self.field_invoice_type.set_enabled(True)
2020-04-19 17:54:08 +02:00
self.clear_data()
2020-12-24 16:19:59 +01:00
self.clear_right_panel()
2020-04-19 17:54:08 +02:00
self.clear_left_panel()
2020-07-27 06:17:17 +02:00
self.message_bar.set('system_ready')
2020-12-29 22:58:21 +01:00
to_create = {
2020-04-19 17:54:08 +02:00
'shop': self.shop['id'],
'invoice_type': 'P',
'company': self.company['id'],
'party': self.default_party['id'],
'sale_device': self.device['id'],
2020-09-17 04:41:10 +02:00
'payment_term': self.default_payment_term['id'],
2020-12-29 22:58:21 +01:00
}
if kind:
kind_dict = {'kind': kind}
to_create.update(kind_dict)
self._sale = self.Sale.new_sale(to_create)
2020-12-29 20:32:42 +01:00
self.store.set(self._sale)
2020-12-29 22:58:21 +01:00
if kind:
self.store.set(kind_dict)
2020-04-19 17:54:08 +02:00
# FIXME ADD MORE
self._sale.update({
'total_amount': 0
})
2020-09-07 04:19:19 +02:00
2020-04-19 17:54:08 +02:00
self.party_id = self.default_party['id']
2020-12-29 20:32:42 +01:00
if self._sale.get('id') and self.field_delivery_charge:
2020-04-19 17:54:08 +02:00
if self.field_delivery_charge:
self.field_delivery_charge.set_enabled(True)
2020-12-23 19:08:37 +01:00
self.change_view_to('order_front')
2020-12-27 20:06:21 +01:00
if self.enviroment == 'restaurant':
self.menu_dash.setDisabled(False)
2020-04-19 17:54:08 +02:00
def _set_sale_date(self):
if self._sale.get('sale_date'):
local_date = self._sale['sale_date']
if isinstance(local_date, date):
local_date = local_date.isoformat()
2020-12-29 20:32:42 +01:00
self.field_sale_date.setText(local_date)
2020-04-19 17:54:08 +02:00
def _search_product(self, code):
domain = [
('template.salable', '=', True),
('template.account_category', '!=', None),
]
domain.append(['OR',
2020-07-27 06:17:17 +02:00
('barcode', '=', code),
('code', '=', code)])
2020-08-06 21:26:18 +02:00
if self.cache_local:
2020-09-07 04:41:19 +02:00
clause = ['OR',
('barcode', '=', '%{:}%'.format(code)),
('code', '=', '%{:}%'.format(code))]
domain = [clause]
2020-12-29 20:32:42 +01:00
products = self.local_db.find_product_elastic(domain, limit=100)
2020-08-06 21:26:18 +02:00
else:
products = self.Product.find(domain, ctx=self.stock_context)
2020-12-10 13:09:40 +01:00
2020-04-19 17:54:08 +02:00
if not products or len(products) > 1:
self.message_bar.set('product_not_found')
return False
else:
product = products[0]
return product
2020-07-27 06:17:17 +02:00
def _check_quantity(self):
2020-08-20 06:40:41 +02:00
for line in self.model_sale_lines._data:
product_id = None
if isinstance(line['product'], int):
product_id = line['product']
elif isinstance(line['product'], dict):
product_id = line['product']['id']
if product_id:
2020-09-12 16:45:18 +02:00
product, = self.Product.find([('id', '=', product_id)], ctx=self.stock_context)
2020-10-15 22:40:54 +02:00
if 'quantity' in product and not self._check_stock_quantity(product):
2020-08-20 06:40:41 +02:00
return False
2020-07-27 06:17:17 +02:00
return True
2020-04-19 17:54:08 +02:00
def check_salesman(self):
2020-12-31 00:39:59 +01:00
salesman = self.store.get('salesman')
if self.salesman_required and not salesman:
2020-04-19 17:54:08 +02:00
dialog = self.dialog('missing_salesman')
dialog.exec_()
return False
return True
2020-12-31 00:12:12 +01:00
def add_product(self, record=None, code=None, list_price=None):
2020-04-19 17:54:08 +02:00
if self._state == 'disabled':
self.message_bar.set('must_load_or_create_sale')
return
product_id = None
2020-12-29 22:58:21 +01:00
if record:
product_id = record['id']
2020-04-19 17:54:08 +02:00
elif code:
# REMOVE ME
product = self._search_product(code)
if product:
product_id = product['id']
elif product:
product_id = product['id']
if not product_id:
self._state = 'warning'
return
data = {
'sale_id': self._sale['id'],
'product_id': product_id,
2020-12-30 22:04:23 +01:00
'qty': 1,
2020-04-19 17:54:08 +02:00
}
2020-12-31 00:12:12 +01:00
if list_price:
data['list_price'] = list_price
2020-12-20 12:14:56 +01:00
res = self.Sale.faster_add_product(data)
2020-04-19 17:54:08 +02:00
self._sale_line = res
self._current_line_id = res['id']
self.add_sale_line(res)
2020-12-29 22:58:21 +01:00
self._sale_line['product'] = record
2020-09-12 18:12:22 +02:00
self.product_id = product_id
2020-04-19 17:54:08 +02:00
2020-12-30 01:02:54 +01:00
self.set_amounts()
2020-04-19 17:54:08 +02:00
self.set_state('add')
2020-07-27 06:17:17 +02:00
def _check_stock_quantity(self, product, request_qty=None):
2020-08-15 00:11:46 +02:00
if not isinstance(product['quantity'], (str, int, float, Decimal)):
return True
2020-07-06 18:57:33 +02:00
qty_ = Decimal(product['quantity'])
if self._password_force_assign:
2020-07-27 06:17:17 +02:00
if (request_qty and qty_ < request_qty) or (qty_ <= 0):
self.message_bar.set('without_stock_quantity', product['name'])
self.dialog_force_assign.exec_()
password = self.field_password_force_assign_ask.text()
self.field_password_force_assign_ask.setText('')
if password != self._password_force_assign:
2020-07-27 06:17:17 +02:00
self.message_bar.set('not_can_force_assign')
return False
else:
self.message_bar.set('system_ready')
2020-04-19 17:54:08 +02:00
return True
def add_sale_line(self, record):
2020-04-23 22:52:05 +02:00
if not record.get('unit.symbol'):
record['unit.symbol'] = record['unit']['symbol']
2020-05-12 17:39:36 +02:00
if isinstance(record['product'], dict):
if not record.get('product.template.name'):
record['product.template.name'] = record['product']['template']['name']
if not record.get('product.code'):
record['product.code'] = record['product']['code']
if record.get('order_sended'):
record['order_sended'] = ''
2020-04-19 17:54:08 +02:00
rec = self.model_sale_lines.add_record(record)
self.field_amount.setText(rec['amount_w_tax'])
2020-09-12 18:12:22 +02:00
def sale_line_selected(self, line):
2020-12-27 20:06:21 +01:00
if self._state in ('cash', 'payment'):
2020-04-19 17:54:08 +02:00
return
2020-12-30 22:04:23 +01:00
2020-12-30 21:51:52 +01:00
self._current_line = line
2020-09-12 18:12:22 +02:00
self._current_line_id = line['id']
2020-09-15 04:53:44 +02:00
product_id = None
if isinstance(line['product'], int):
product_id = line['product']
elif isinstance(line['product'], dict):
product_id = line['product']['id']
self.product_id = product_id
2020-09-12 18:12:22 +02:00
self.label_product.setText(line['product.template.name'])
self.row_field_description.setText(line['description'])
self.row_field_qty.setValue(float(line['quantity']))
self.row_field_price.setText(str(line['unit_price_w_tax']))
2020-12-22 21:20:39 +01:00
self.row_field_note.setText(str(line['note']))
2020-04-19 17:54:08 +02:00
self.dialog_product_edit.show()
self.row_field_note.setFocus()
2020-09-17 04:41:10 +02:00
def sale_consumer_selected(self, data):
self.sale_customer_selected = data['id']
self.row_sale_party.setText(data['party']['name'])
self.row_sale_number.setText(data['number'])
self.row_sale_date.setText(data['sale_date'])
self.row_sale_tax_amount.setText(str(data['tax_amount']))
self.row_sale_untaxed.setText(str(data['untaxed_amount']))
self.row_sale_total.setText(str(data['total_amount_cache']))
self.model_sale_customer_lines.reset()
for line in data['lines']:
self.model_sale_customer_lines.add_record(line)
self.dialog_sale_consumer_selected.exec_()
def clear_delivery_party(self):
self._delivery_party_selected = None
2020-12-29 20:32:42 +01:00
self.row_delivery_party.setText('')
2020-09-17 04:41:10 +02:00
self.row_id_number.setText('')
self.row_phone.setText('')
2020-09-17 04:41:10 +02:00
self.row_number_plate.setText('')
self.row_type_vehicle.set_from_id('')
2020-12-29 20:32:42 +01:00
self.row_delivery_party_active.setChecked(True)
2020-09-17 04:41:10 +02:00
2020-09-15 04:53:44 +02:00
def delivery_party_selected(self, data):
2020-09-17 04:41:10 +02:00
self._delivery_party_selected = data['id']
2020-12-29 20:32:42 +01:00
self.row_delivery_party.setText(data['rec_name'])
self.row_id_number.setText(data['party']['id_number'])
2020-09-15 04:53:44 +02:00
self.row_number_plate.setText(data['number_plate'])
2020-09-19 17:06:14 +02:00
if data.get('type_vehicle'):
self.row_type_vehicle.set_from_id(data['type_vehicle'])
2020-12-29 20:32:42 +01:00
self.row_delivery_party_active.setChecked(data['active'])
2020-09-15 04:53:44 +02:00
self.dialog_delivery_party_selected.show()
2020-12-29 20:32:42 +01:00
self.row_delivery_party_active.setFocus()
2020-09-15 04:53:44 +02:00
2020-09-09 21:22:35 +02:00
def setup_money_count(self):
2020-12-23 14:04:57 +01:00
self.model_money_count = TableModelEdit(self, MONEY)
2020-09-09 21:22:35 +02:00
2020-04-19 17:54:08 +02:00
def setup_sale_line(self):
product_code = {
'name': 'product.code',
'align': alignRight,
'description': self.tr('COD'),
'width': 80
}
product = {
'name': 'product.template.name',
'align': alignLeft,
'description': self.tr('NAME'),
'width': STRETCH
}
description = {
'name': 'description',
'align': alignLeft,
'description': self.tr('DESCRIPTION'),
'width': 180
}
uom = {
'name': 'unit.symbol',
'align': alignHCenter,
'description': self.tr('UNIT'),
'width': 50
}
qty = {
'name': 'quantity',
'format': '{:3,.%sf}',
'align': alignRight,
'description': self.tr('QTY'),
'digits': ('unit.symbol', CONVERSION_DIGITS),
'width': 80
}
discount = {
'name': 'discount',
'format': '{0:.0%}',
'align': alignRight,
'description': self.tr('DISC'),
'width': 50
}
amount = {
'name': 'amount_w_tax',
2020-12-11 22:47:46 +01:00
'format': '{:,d}',
2020-04-19 17:54:08 +02:00
'align': alignRight,
'description': self.tr('SUBTOTAL'),
'width': 100
}
note = {
'name': 'note',
'align': alignLeft,
'description': self.tr('NOTE'),
2020-12-30 01:02:54 +01:00
'invisible': True,
2020-04-19 17:54:08 +02:00
'width': 100
}
unit_price = {
'name': 'unit_price_w_tax',
'format': '{:5,.1f}',
'align': alignLeft,
'description': self.tr('UNIT PRICE W TAX'),
'invisible': True,
'width': 100
}
qty_fraction = {
'name': 'qty_fraction',
'align': alignHCenter,
'description': self.tr('FRAC'),
'width': 50
}
commanded = {
'name': 'order_sended',
'align': alignHCenter,
'description': self.tr('COMMANDED'),
2020-12-06 05:09:41 +01:00
'width': 60
}
2020-04-19 17:54:08 +02:00
self.fields_sale_line = [product, uom, qty, discount,
amount, note, unit_price]
if self.enviroment == 'retail':
self.fields_sale_line.insert(0, product_code)
if self.enviroment == 'restaurant':
self.fields_sale_line.insert(1, commanded)
2020-04-19 17:54:08 +02:00
if self._config.get('show_description_pos'):
self.fields_sale_line.insert(2, description)
if self._config.get('show_fractions'):
self.fields_sale_line.insert(4, qty_fraction)
self.model_sale_lines = TableModel('sale.line', self.fields_sale_line)
2020-09-17 04:41:10 +02:00
self.model_sale_customer_lines = TableModel('sale.line', self.fields_sale_line)
def setup_sale_consumer(self):
number = {
'name': 'number',
'align': alignCenter,
'description': self.tr('NUMBER'),
'width': 200
}
invoice_number = {
'name': 'invoice_number',
'align': alignCenter,
'description': self.tr('INVOICE NUMBER'),
'width': 200
}
consumer = {
'name': 'consumer.name',
'align': alignCenter,
'description': self.tr('CONSUMER'),
'width': 300
}
sale_date = {
'name': 'sale_date',
'align': alignCenter,
'description': self.tr('DATE'),
'width': 300
}
total_amount_cache = {
'name': 'total_amount_cache',
'align': alignCenter,
'description': self.tr('TOTAL AMOUNT'),
'width': 300
}
self.fields_sale_consumer = [number, invoice_number, consumer, sale_date,
total_amount_cache]
self.model_sale_consumer = TableModel('sale.sale', self.fields_sale_consumer)
2020-04-19 17:54:08 +02:00
2020-09-15 04:53:44 +02:00
def setup_delivery_party(self):
party = {
'name': 'rec_name',
'align': alignLeft,
'description': self.tr('PARTY'),
'width': 380
}
id_number = {
'name': 'party.id_number',
'align': alignLeft,
'description': self.tr('ID NUMBER'),
'width': 200
}
phone = {
'name': 'party.phone',
'align': alignLeft,
'description': self.tr('PHONE'),
'width': 200
}
2020-09-15 04:53:44 +02:00
number_plate = {
'name': 'number_plate',
'align': alignCenter,
'description': self.tr('NUMBER PLATE'),
'width': 200
}
type_vehicle = {
'name': 'type_vehicle',
'align': alignCenter,
'description': self.tr('TYPE VEHICLE'),
'width': 300
}
self.fields_delivery_party = [party, id_number, phone, number_plate, type_vehicle]
2020-09-15 04:53:44 +02:00
self.model_delivery_party = TableModel('sale.delivery_party', self.fields_delivery_party)
2020-09-19 17:06:14 +02:00
for record in self.delivery_man_table:
2020-09-15 04:53:44 +02:00
self.model_delivery_party.add_record(record)
2020-12-29 20:32:42 +01:00
self.delivery_parties = [d for d in self.model_delivery_party._data if d['active']]
2020-09-15 04:53:44 +02:00
2020-04-19 17:54:08 +02:00
def setup_payment(self):
pay_fields = [{
'name': 'statement',
'align': alignLeft,
'description': self.tr('STATEMENT JOURNAL'),
}, {
'name': 'amount',
'align': alignRight,
'format': '{:5,.1f}',
'description': self.tr('AMOUNT'),
}, {
'name': 'voucher',
'align': alignCenter,
'description': self.tr('VOUCHER'),
}]
self.table_payment_lines = TableModel('account.statement.line', pay_fields)
def action_table(self):
self.table_sale_lines.setFocus()
def on_change_line_selected(self, key):
self.table_sale_lines.moved_selection(key)
2020-12-30 21:51:52 +01:00
def action_addition_line(self):
if not self._current_line:
return
categories = self._current_line['product'].get('categories')
if not categories:
return
categories_ids = [cat['id'] for cat in categories]
mixables = self.Product.find([
('categories', 'in', categories_ids),
])
self.dialog_addition_product.set_products(mixables)
self.dialog_addition_product.exec_()
2020-12-31 00:12:12 +01:00
self.dialog_addition_product.close()
2020-12-30 21:51:52 +01:00
2020-04-19 17:54:08 +02:00
def action_delete_line(self):
2020-12-22 21:20:39 +01:00
"""Delete Product """
2020-04-19 17:54:08 +02:00
if self.model_sale_lines.rowCount() <= 0 or self._state == 'cash':
return
self.table_sale_lines.setFocus()
2020-08-05 19:20:33 +02:00
2020-12-22 21:20:39 +01:00
# if not removed_item:
removed_item = self.table_sale_lines.delete_item(ignore_focus=True)
2020-12-20 12:14:56 +01:00
self.SaleLine.delete([removed_item['id']])
2020-04-19 17:54:08 +02:00
self.set_amounts()
self._current_line_id = None
self.setFocus()
self.label_input.setFocus()
2020-12-22 21:20:39 +01:00
self.dialog_product_edit.hide()
2020-12-31 00:12:12 +01:00
sale_number = self.store.get('number')
2020-04-19 17:54:08 +02:00
if self.enviroment == 'restaurant':
2020-12-31 00:12:12 +01:00
if removed_item and self.print_order and sale_number:
2020-04-19 17:54:08 +02:00
self.action_print_order(self._sale['id'], removed_item)
2020-09-17 17:20:21 +02:00
if self._config['tip_product']['code'] == removed_item['product.code']:
2020-12-20 12:14:56 +01:00
self.Sale.write([self._sale['id']], {'tip': None})
2020-04-19 17:54:08 +02:00
def set_discount(self, eval_value, lines_ids=[]):
res = False
try:
value = round(float(str(eval_value)), 6)
except ValueError:
logging.warning('ValueError > ', ValueError)
return
2020-07-09 00:37:50 +02:00
if float(value) < 0:
return False
2020-04-19 17:54:08 +02:00
if not lines_ids:
target_lines = [self._current_line_id]
else:
target_lines = lines_ids
2020-07-06 21:14:00 +02:00
2020-12-20 12:14:56 +01:00
records = self.SaleLine.faster_set_discount({
2020-04-19 17:54:08 +02:00
'line_ids': target_lines,
'value': value
})
for rec in records:
self.model_sale_lines.update_record(rec)
if records:
res = True
self.set_amounts()
return res
def set_unit_price(self, value):
2020-12-20 12:14:56 +01:00
rec = self.SaleLine.set_faster_unit_price({
2020-04-19 17:54:08 +02:00
'id': self._current_line_id,
'value': value,
})
if rec:
self.model_sale_lines.update_record(rec)
2020-12-30 01:02:54 +01:00
self.set_amounts()
2020-04-19 17:54:08 +02:00
return True
return False
def add_payment(self, amount, cash_received=0, change=0):
voucher_number = None
2020-12-31 02:21:43 +01:00
if not self.journal:
journal = self.default_journal
else:
journal = self.journal
if journal.get('require_voucher'):
2020-04-19 17:54:08 +02:00
self.dialog_voucher.exec_()
voucher_number = self.field_voucher_ask.text()
if voucher_number is None or voucher_number == '':
return self.add_payment(amount)
2020-12-20 12:14:56 +01:00
res = self.Sale.faster_add_payment({
2020-04-19 17:54:08 +02:00
'sale_id': self._sale['id'],
2020-12-31 02:21:43 +01:00
'journal_id': journal['id'],
2020-04-19 17:54:08 +02:00
'amount': to_numeric(amount),
'voucher_number': voucher_number,
'cash_received': to_numeric(cash_received),
'change': to_numeric(change)
})
if res.get('msg') not in ('missing_money', 'ok'):
self.dialog(res['msg'])
return res
2020-12-31 21:34:12 +01:00
residual_amount = res.pop('residual_amount')
change = res.pop('change')
paid_amount = res.pop('paid_amount')
self.store.set({
'residual_amount': residual_amount,
'change': change,
'paid_amount': paid_amount,
})
2020-04-19 17:54:08 +02:00
self.table_payment_lines.add_record(res)
return res
def set_keys(self):
self.keys_numbers = list(range(Qt.Key_0, Qt.Key_9 + 1))
self.keys_alpha = list(range(Qt.Key_A, Qt.Key_Z + 1))
self.keys_period = [Qt.Key_Period]
self.show_keys = self.keys_numbers + self.keys_alpha + self.keys_period
2020-07-27 06:17:17 +02:00
self.keys_special = [Qt.Key_Asterisk, Qt.Key_Comma, Qt.Key_Minus, Qt.Key_Slash]
2020-04-19 17:54:08 +02:00
self.keys_input = [Qt.Key_Backspace]
self.keys_input.extend(self.keys_special)
self.keys_input.extend(self.show_keys)
self.keys_input.extend(self.keys_numbers)
self.keys_input.extend([Qt.Key_Return, Qt.Key_Plus])
def set_state(self, state='add'):
self._state = state
state = STATES[state]
self._re = state['re']
if not self.type_pos_user == 'order':
2020-12-27 17:30:02 +01:00
if not self.buttons_stacked.stacked.currentWidget():
2020-04-19 17:54:08 +02:00
return
if state['button']:
2020-12-27 17:30:02 +01:00
self.buttons_stacked.stacked.setCurrentWidget(
getattr(self.buttons_stacked, state['button'])
2020-04-19 17:54:08 +02:00
)
2020-12-27 17:30:02 +01:00
self.buttons_stacked.stacked.currentWidget().setVisible(True)
2020-04-19 17:54:08 +02:00
else:
2020-12-27 17:30:02 +01:00
self.buttons_stacked.stacked.currentWidget().setVisible(False)
2020-04-19 17:54:08 +02:00
def key_pressed(self, text):
2020-12-27 20:06:21 +01:00
if not self._sign and self._state not in ('cash', 'payment'):
2020-12-24 00:53:28 +01:00
# FIXME
# if self._re.match(self._input_text + text):
# self.input_text_changed(text)
pass
2020-04-19 17:54:08 +02:00
else:
if RE_SIGN['quantity'].match(self._amount_text + text):
self.amount_text_changed(text)
def clear_sign(self):
self._sign = None
self.field_sign.setText(' {0} '.format(' '))
def sign_text_changed(self, sign):
self._sign = sign
self.field_sign.setText(' {0} '.format(sign))
if hasattr(self, '_sale_line') and self._sale_line:
if sign == '-':
self.message_bar.set('enter_discount')
elif sign == '/':
self.message_bar.set('enter_new_price')
elif sign == '*':
self.message_bar.set('enter_quantity')
if self.active_weighing and self._sale_line['unit_symbol'] != 'u':
self.action_read_weight()
def key_special_pressed(self, value):
self.clear_amount_text()
self.clear_input_text()
if value not in ['-', '/', '*']:
return
self.sign_text_changed(value)
def key_backspace_pressed(self):
2020-12-27 20:06:21 +01:00
if self._sign or self._state in ('cash', 'payment'):
2020-04-19 17:54:08 +02:00
self._amount_text = self._amount_text[:-1]
self.amount_text_changed()
2020-12-27 20:06:21 +01:00
self.label_input.setFocus()
2020-04-19 17:54:08 +02:00
else:
self._input_text = self._input_text[:-1]
self.input_text_changed()
def set_text(self, text):
if not self._state == 'cash':
self.input_text_changed(text)
else:
self.amount_text_changed(text)
def clear_input_text(self):
self.input_text_changed('')
def clear_amount_text(self):
self._amount_text = '0'
self.amount_text_changed()
def keyPressEvent(self, event):
self._keyStates[event.key()] = True
key = event.key()
if self._state == 'add' and key not in self.keys_input and \
key not in (Qt.Key_Enter, Qt.Key_End):
# Clear ui context when keys function are pressed
self._clear_context()
if key in (Qt.Key_Return, Qt.Key_Plus):
self.button_plus_pressed()
elif key in self.show_keys:
# No allow change quantity o discount in state == cash
2020-12-27 20:06:21 +01:00
if self._state in ('cash', 'payment') and key not in self.keys_numbers:
2020-04-19 17:54:08 +02:00
return
self.key_pressed(event.text())
elif key in self.keys_special:
if self._state == 'cash' or not self._current_line_id:
return
self.key_special_pressed(event.text())
elif key == Qt.Key_Backspace:
self.key_backspace_pressed()
elif key == Qt.Key_Escape:
2020-12-27 20:06:21 +01:00
if self._state not in ('cash', 'payment'):
self._clear_context()
# self.close()
2020-04-19 17:54:08 +02:00
elif key == Qt.Key_F1:
2020-09-03 06:00:57 +02:00
# help = Help(self).show()
self.action_control_panel()
2020-04-19 17:54:08 +02:00
elif key == Qt.Key_F9:
self.action_search_sale()
elif key == Qt.Key_F11:
self.action_new_sale()
elif key == Qt.Key_F7:
self.action_print_sale()
elif self._state == 'disabled':
self.message_bar.set('must_load_or_create_sale')
return
elif key in (Qt.Key_Enter, Qt.Key_End):
if self.type_pos_user in ['order', 'salesman']:
return
if self._state == 'add':
self.button_accept_pressed()
2020-09-16 00:22:58 +02:00
elif self._state in ['cash', 'accept']:
2020-04-19 17:54:08 +02:00
self.button_cash_pressed()
elif key == Qt.Key_F2:
self.action_search_product()
elif key == Qt.Key_F3:
self.action_payment()
elif key == Qt.Key_F4:
self.action_party()
elif key == Qt.Key_F5:
self.action_global_discount()
elif key == Qt.Key_F6:
self.action_print_order()
elif key == Qt.Key_F8:
self.action_payment_term()
elif key == Qt.Key_F10:
self.action_table()
elif key == Qt.Key_F12:
self.action_cancel()
elif key == Qt.Key_Home:
self.action_salesman()
elif key == Qt.Key_Down or key == Qt.Key_Up:
self.on_change_line_selected(key)
elif key == Qt.Key_Insert:
self.action_position()
elif key == Qt.Key_Semicolon and self._commission_activated:
sale = self.get_current_sale()
2020-12-27 20:06:21 +01:00
if sale['state'] == 'draft' and self._state not in ['cash', 'payment']:
2020-04-19 17:54:08 +02:00
self.action_agent()
elif key == Qt.Key_QuoteDbl:
self.action_comment()
elif key == Qt.Key_Question:
self.action_tax()
@property
def state(self):
return self._state
2020-07-28 23:54:15 +02:00
def update_sale_line(self, field):
value = None
self.state_line['id'] = self._current_line_id
if field == 'quantity':
value = Decimal(self.row_field_qty.value())
if field == 'unit_price':
value = self.row_field_price.text()
if field == 'qty_fraction':
qty = self.field_combobox_fraction.get_id()
self.row_field_qty.setValue(float(qty))
value = self.field_combobox_fraction.get_label()
self.state_line['quantity'] = qty
2020-12-20 12:14:56 +01:00
price_ = self.Sale.get_product_prices({
2020-07-28 23:54:15 +02:00
'ids': [self._sale_line['product']['id']],
'quantity': float(qty),
'sale_id': self._sale['id'],
})
if price_ and price_.get('unit_price_w_tax'):
price_list = str(price_['unit_price_w_tax'])
self.row_field_price.setText(price_list)
self.state_line['unit_price'] = price_list
if field == 'description':
value = self.row_field_description.text()
if field == 'note':
value = self.row_field_note.toPlainText()
if value:
self.state_line[field] = value
def dialog_product_edit_accepted(self):
if not self.state_line:
return
_record = None
if self.state_line.get('unit_price'):
unit_price = self.state_line.pop('unit_price')
self._sign = '/'
self._process_price(unit_price)
self._sign = None
2020-12-20 12:14:56 +01:00
_record = self.SaleLine.write([self._current_line_id], {})
2020-07-28 23:54:15 +02:00
2020-09-12 16:45:18 +02:00
if self.state_line.get('quantity'):
quantity = self.state_line.pop('quantity')
2020-12-24 02:45:56 +01:00
_record = self.SaleLine.faster_set_quantity({
'id': self._current_line_id,
'quantity': to_float(quantity, 2)
})
2020-09-12 16:45:18 +02:00
2020-07-28 23:54:15 +02:00
if self.state_line.get('description'):
2020-12-20 12:14:56 +01:00
_record = self.SaleLine.write([self._current_line_id], {
2020-07-28 23:54:15 +02:00
'description': self.state_line['description']
})
if self.state_line.get('note'):
2020-12-20 12:14:56 +01:00
_record = self.SaleLine.write([self._current_line_id], {
2020-07-28 23:54:15 +02:00
'note': self.state_line['note']
})
if _record:
if not _record.get('unit.symbol'):
_record['unit.symbol'] = _record['unit']['symbol']
if not _record.get('product.template.name'):
_record['product.template.name'] = _record['product']['template']['name']
if not _record.get('product.code'):
_record['product.code'] = _record['product']['code']
self.model_sale_lines.update_record(_record)
2020-12-30 01:02:54 +01:00
self.set_amounts()
2020-07-28 23:54:15 +02:00
self.state_line = {}
def dialog_search_consumer_accepted(self):
if not self.state_consumer:
return
if self._consumer:
2020-12-20 12:14:56 +01:00
res = self.Sale.update_consumer({
2020-07-28 23:54:15 +02:00
'id': self._consumer['id'],
'fields': self.state_consumer,
})
else:
2020-12-20 12:14:56 +01:00
res = self.Sale.create_consumer({
2020-07-28 23:54:15 +02:00
'fields': self.state_consumer,
})
2020-12-20 22:52:28 +01:00
if res.get('msg') == 'ok':
2020-12-27 02:42:04 +01:00
self._consumer = res['consumer']
self.consumer_id = self._consumer['id']
2020-12-20 22:52:28 +01:00
self._sale['consumer'] = self.consumer_id
2020-12-27 02:42:04 +01:00
self.set_consumer()
self.field_consumer.setText(self._consumer['name'])
2020-12-20 12:14:56 +01:00
self.Sale.write([self._sale['id']], {'consumer': self.consumer_id})
2020-08-20 06:40:41 +02:00
if res.get('party'):
self.on_selected_party(res['party'])
2020-12-29 20:32:42 +01:00
def dialog_delivery_party_accepted(self):
2020-09-15 04:53:44 +02:00
if not self.state_delivery_party:
return
if hasattr(self, '_delivery_party_selected') and self._delivery_party_selected:
2020-12-20 12:14:56 +01:00
res = self.Sale.update_delivery_party({
2020-09-19 02:52:39 +02:00
'id': self._delivery_party_selected,
'data': self.state_delivery_party
})
self._delivery_party_selected = None
2020-09-19 17:06:14 +02:00
self.model_delivery_party.update_record(res)
2020-09-19 02:52:39 +02:00
else:
2020-12-20 12:14:56 +01:00
res = self.Sale.create_delivery_party({
2020-09-19 02:52:39 +02:00
'data': self.state_delivery_party,
'shop_id': self.ctx['shop']
})
self.model_delivery_party.add_record(res)
2020-09-19 17:06:14 +02:00
2020-12-29 20:32:42 +01:00
self.delivery_parties = [d for d in self.model_delivery_party._data if d['active']]
self.dialog_delivery_party = DialogDeliveryParty(self).get()
2020-09-15 04:53:44 +02:00
def update_delivery_party(self, field=''):
2020-12-29 20:32:42 +01:00
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()
2020-09-17 04:41:10 +02:00
if field == 'id_number':
self.state_delivery_party['id_number'] = self.row_id_number.text()
2020-09-15 04:53:44 +02:00
if field == 'number_plate':
self.state_delivery_party['number_plate'] = self.row_number_plate.text()
if field == 'type_vehicle':
2020-09-17 04:41:10 +02:00
self.state_delivery_party['type_vehicle'] = self.row_type_vehicle.get_id()
2020-12-29 20:32:42 +01:00
if field == 'delivery_party_active':
self.state_delivery_party['active'] = self.row_delivery_party_active.isChecked()
2020-07-28 23:54:15 +02:00
def update_consumer_data(self, field=''):
2020-12-21 17:03:44 +01:00
if field == 'notes':
self.state_consumer['notes'] = self.row_field_consumer_notes.toPlainText()
2020-07-28 23:54:15 +02:00
if field == 'address':
self.state_consumer['address'] = self.row_field_address.text()
elif field == 'id_number':
self.state_consumer['id_number'] = self.row_field_id_number.text()
elif field == 'name':
self.state_consumer['name'] = self.row_field_consumer.text()
elif field == 'birthday':
self.state_consumer['birthday'] = self.row_field_birthday.date().toPyDate()
elif field == 'phone':
self._text_field_phone = self.row_field_phone.text()
if self._text_field_phone:
self.state_consumer['phone'] = self._text_field_phone
consumers = self.PartyConsumer.find([
('phone', '=', self._text_field_phone),
])
2020-12-20 22:52:28 +01:00
2020-07-28 23:54:15 +02:00
if not consumers:
self._consumer = {}
self.row_field_address.setText('')
self.row_field_consumer.setText('')
self.row_field_id_number.setText('')
2020-09-03 06:00:57 +02:00
self.row_field_birthday.setDate(MINIMUM_DATE)
2020-12-21 17:03:44 +01:00
self.row_field_consumer_notes.clear()
2020-07-28 23:54:15 +02:00
else:
2020-09-17 04:41:10 +02:00
self.button_history_customer.setVisible(True)
2020-07-28 23:54:15 +02:00
self._consumer = consumers[0]
2020-12-21 17:03:44 +01:00
self.set_consumer()
# self.row_field_address.setText(self._consumer['address'])
# self.row_field_consumer.setText(self._consumer['name'])
# self.row_field_id_number.setText(self._consumer['id_number'])
# self.row_field_consumer_notes.insertPlainText(
# self._consumer['notes'])
# if self._consumer.get('birthday'):
# y, m, d = self._consumer['birthday'].split('-')
# self.row_field_birthday.setDate(QDate(int(y), int(m), int(d)))
2020-07-28 23:54:15 +02:00
2020-12-20 22:52:28 +01:00
def action_table_assigned(self, table, name, trasition_state):
current_table = self._sale.get('table_assigned')
current_sale_id = self._sale['id']
table_id = table['id']
2020-07-28 23:54:15 +02:00
2020-12-20 22:52:28 +01:00
table_sale_id = table['sale_id']
new_table_id = table_id
table_state = table['state']
sale_id = current_sale_id
if table_state == 'occupied':
if current_sale_id != table_sale_id and trasition_state == 'occupied':
return False
elif current_table and current_table['id'] == table_id and trasition_state == 'available':
name = ''
new_table_id = None
current_sale_id = None
2020-07-28 23:54:15 +02:00
2020-12-30 15:42:08 +01:00
vals = {'table_assigned': {
2020-12-20 22:52:28 +01:00
'id': table_id,
2020-12-20 18:21:17 +01:00
'name': name,
2020-12-30 15:42:08 +01:00
}}
self.store.set(vals)
# self._sale['table_assigned.state'] = trasition_state
2020-12-20 17:05:04 +01:00
self.RestTables.write([table_id], {
'state': trasition_state,
2020-12-20 22:52:28 +01:00
'sale': current_sale_id,
2020-12-20 17:05:04 +01:00
})
2020-07-28 23:54:15 +02:00
2020-12-30 15:42:08 +01:00
self.Sale.write([self.store.sale_id], {'table_assigned': new_table_id})
2020-12-20 18:21:17 +01:00
return {
'state': trasition_state,
'sale': sale_id,
}
2020-07-28 23:54:15 +02:00
2020-12-20 17:05:04 +01:00
def action_see_table_sale(self, table_id):
table_, = self.RestTables.find([
('id', '=', table_id),
], limit=1)
sale = table_['sale']
if sale:
self.load_sale(sale['id'])
self.dialog_manage_tables.hide()
2020-08-20 06:40:41 +02:00
def clear_dialog_consumer(self):
2020-09-17 04:41:10 +02:00
self._consumer = {}
2020-07-28 23:54:15 +02:00
self.row_field_phone.setText('')
self.row_field_address.setText('')
self.row_field_consumer.setText('')
self.row_field_id_number.setText('')
2020-09-03 06:00:57 +02:00
self.row_field_birthday.setDate(QDate(2000, 1, 1))
2020-12-21 17:03:44 +01:00
self.row_field_consumer_notes.clear()
2020-09-17 04:41:10 +02:00
self.button_history_customer.setVisible(False)
2020-07-28 23:54:15 +02:00
2020-12-21 17:03:44 +01:00
def set_consumer(self):
2020-12-27 02:42:04 +01:00
self.row_field_consumer_notes.clear()
2020-12-21 17:03:44 +01:00
self.row_field_phone.setText(self._consumer['phone'])
self.row_field_consumer.setText(self._consumer['name'])
self.row_field_address.setText(self._consumer['address'])
2020-12-27 02:42:04 +01:00
id_number = self._consumer.get('id_number')
if id_number:
self.row_field_id_number.setText(id_number)
2020-12-21 17:03:44 +01:00
self.row_field_consumer_notes.insertPlainText(
2020-12-27 02:42:04 +01:00
self._consumer['notes']
)
2020-12-21 17:03:44 +01:00
if self._consumer.get('birthday'):
y, m, d = self._consumer['birthday'].split('-')
self.row_field_birthday.setDate(QDate(int(y), int(m), int(d)))
2020-12-29 20:32:42 +01:00
# 2798