Files
enterprise-addons/l10n_de_pos_res_cert/models/pos_order.py
T

136 lines
5.6 KiB
Python

# -*- coding: utf-8 -*-
from odoo import models, api
from itertools import groupby
class PosOrder(models.Model):
_inherit = 'pos.order'
@api.model
def _check_config_germany_floor(self, session_id=None, order_id=None):
"""
Check if the pos config is from a company located in Germany and if it has at least one floor
The pos config is retrieved either by the session_id if the order has not been created yet,
otherwise from an id of an order
"""
config = None
if session_id:
config = self.env['pos.session'].browse(session_id).config_id
elif order_id:
config = self.browse(order_id).config_id
return bool(config and config.company_id.l10n_de_is_germany_and_fiskaly() and config.floor_ids)
def read_pos_data(self, data, config):
result = super().read_pos_data(data, config)
if not len(self):
return result
session_id = self[0].session_id.id
if not self._check_config_germany_floor(session_id=session_id):
return result
order_differences = {}
for ui_order in data:
if ui_order['state'] == 'draft':
existing_order = None
if ui_order.get('id'):
existing_order = self.env['pos.order'].browse(ui_order['id']).exists()
if not existing_order or existing_order.state == 'draft':
differences = self._line_differences(existing_order, ui_order)
if differences:
order_differences[ui_order['pos_reference']] = differences
for json_record in result['pos.order']:
if json_record['pos_reference'] in order_differences:
json_record['differences'] = order_differences[json_record['pos_reference']]
return result
@api.model
def _line_differences(self, existing_order, ui_order=None):
"""
:param existing_order: actual PosOrder object
:param ui_order: json order coming from the front end or None
:return: a list of lines difference
"""
new_line_dict = {} if not ui_order else self._merge_order_lines(
[line[2] for line in ui_order['lines'] if line[0] in [0, 1] and line[2]['qty'] != 0]
)
old_lines = []
if existing_order:
old_lines = existing_order.lines.read(['qty', 'product_id', 'full_product_name', 'price_subtotal_incl',
'price_unit', 'discount'])
for line in old_lines:
line['product_id'] = line['product_id'][0]
old_line_dict = self._merge_order_lines(old_lines)
differences = []
for new_line_key, new_line in new_line_dict.items():
if new_line_key not in old_line_dict:
differences.append(new_line)
elif old_line_dict[new_line_key]['qty'] != new_line['qty']:
# we could copy the dict but since it's not going to be used anymore we can just modify it
new_line['qty'] -= old_line_dict[new_line_key]['qty']
differences.append(new_line)
for old_line_key, old_line in old_line_dict.items():
if old_line_key not in new_line_dict:
old_line['qty'] = -old_line['qty']
differences.append(old_line)
return differences
@api.model
def _merge_order_lines(self, order_lines):
"""
It is possible to have multiple lines regarding the same product with the same unit price.
This method will merge those lines into one. The lines with the same product but with different price or
discount will be considered different.
This method create a dictionary with the required information by triplet (id, price, discount).
(note: the 'price_per_unit' is the full price of the product (vat + discount))
:param order_lines: The list of lines in a dictionary format
:return: {(id[int], price[int], discount[int]): {'qty': float, 'text': string, 'price_per_unit': float} }
"""
def keys(line):
return (line['product_id'], line['price_unit'], line.get('discount', 0))
line_dict = {}
for k, g in groupby(sorted(order_lines, key=keys), key=keys):
group = list(g)
unit_price = group[0]['price_subtotal_incl']/group[0]['qty']
line_dict[k] = {
'qty': sum(line['qty'] for line in group),
'text': group[0]['full_product_name'],
'price_per_unit': unit_price
}
return line_dict
@api.model
def retrieve_line_difference(self, ui_orders):
"""This method is deprecated and will be removed in master (saas-19.1)."""
res = {}
for order in ui_orders:
existing_order = None if not order.get('access_token') else self.search([('access_token', '=', order.get('access_token'))])
res[order['uuid']] = self._line_differences(existing_order, order)
return res
@api.model
def remove_from_ui(self, server_ids):
"""
Almost the same as the original method except that we compute the line difference and add it to the response
"""
if self.env.company.l10n_de_is_germany_and_fiskaly():
orders = self.search([('id', 'in', server_ids), ('state', '=', 'draft')])
res = []
for order in orders:
differences = self._line_differences(order)
res.append({'id': order.id, 'differences': differences})
super().remove_from_ui(server_ids)
return res
else:
return super().remove_from_ui(server_ids)