113 lines
4.7 KiB
Python
113 lines
4.7 KiB
Python
# -*- coding: utf-8 -*-
|
|
|
|
from odoo import models, fields, api, _
|
|
|
|
import logging
|
|
_logger = logging.getLogger(__name__)
|
|
|
|
class PosOrder(models.Model):
|
|
_inherit = 'pos.order'
|
|
|
|
@api.model
|
|
def create_quotation_from_pos_lines(self, partner_id, lines_data, config_id):
|
|
"""
|
|
Creates a new sale.order (Quotation) from standard POS lines,
|
|
leaving out the downpayment product.
|
|
|
|
:param partner_id: int, ID of the partner for the Quotation
|
|
:param lines_data: list of dicts, details of POS lines
|
|
:param config_id: int, ID of pos.config to get the downpayment product
|
|
:return: dict with 'id' and 'name' of the created sale.order
|
|
"""
|
|
try:
|
|
pos_config = self.env['pos.config'].browse(config_id)
|
|
down_payment_product_id = pos_config.down_payment_product_id.id
|
|
|
|
if not partner_id:
|
|
return False
|
|
|
|
sale_order = self.env['sale.order'].create({
|
|
'partner_id': partner_id,
|
|
})
|
|
|
|
# Add lines to the sale.order
|
|
for line in lines_data:
|
|
if line['product_id'] != down_payment_product_id:
|
|
# Prepare tax IDs
|
|
tax_ids = line.get('tax_ids', [])
|
|
if isinstance(tax_ids, list) and not tax_ids:
|
|
tax_ids = []
|
|
|
|
product = self.env['product.product'].browse(line['product_id'])
|
|
|
|
self.env['sale.order.line'].create({
|
|
'order_id': sale_order.id,
|
|
'product_id': product.id,
|
|
'name': product.display_name or product.name,
|
|
'product_uom_qty': line['qty'],
|
|
'price_unit': line['price_unit'],
|
|
'discount': line.get('discount', 0.0),
|
|
'tax_id': [(6, 0, tax_ids)],
|
|
})
|
|
|
|
return {
|
|
'id': sale_order.id,
|
|
'name': sale_order.name,
|
|
}
|
|
except Exception as e:
|
|
_logger.error("Error creating quotation from POS lines: %s", repr(e), exc_info=True)
|
|
raise e
|
|
|
|
def _create_order_picking(self):
|
|
self.ensure_one()
|
|
if self.shipping_date:
|
|
self.sudo().lines.filtered(lambda l: not l.is_quotation_line)._launch_stock_rule_from_pos_order_lines()
|
|
else:
|
|
if self._should_create_picking_real_time():
|
|
picking_type = self.config_id.picking_type_id
|
|
if self.partner_id.property_stock_customer:
|
|
destination_id = self.partner_id.property_stock_customer.id
|
|
elif not picking_type or not picking_type.default_location_dest_id:
|
|
destination_id = self.env['stock.warehouse']._get_partner_locations()[0].id
|
|
else:
|
|
destination_id = picking_type.default_location_dest_id.id
|
|
|
|
lines_to_pick = self.lines.filtered(lambda l: not l.is_quotation_line)
|
|
if lines_to_pick:
|
|
pickings = self.env['stock.picking']._create_picking_from_pos_order_lines(destination_id, lines_to_pick, picking_type, self.partner_id)
|
|
pickings.write({'pos_session_id': self.session_id.id, 'pos_order_id': self.id, 'origin': self.name})
|
|
|
|
def _process_preparation_changes(self, cancelled=False, note_history=None):
|
|
"""
|
|
Intercepts preparation display generation. If this POS order is actually a Quotation
|
|
we don't want it to be processed by the kitchen display.
|
|
"""
|
|
if any(line.is_quotation_line for line in self.lines):
|
|
return {'change': False, 'sound': False, 'category_ids': []}
|
|
# Check if pos_preparation_display is installed and we can call super
|
|
if hasattr(super(), '_process_preparation_changes'):
|
|
return super()._process_preparation_changes(cancelled=cancelled, note_history=note_history)
|
|
return {'change': False, 'sound': False, 'category_ids': []}
|
|
|
|
|
|
class PosOrderLine(models.Model):
|
|
_inherit = 'pos.order.line'
|
|
|
|
is_quotation_line = fields.Boolean(
|
|
string='Is Quotation Line',
|
|
help='Indicates this line was converted to a quotation and its price was zeroed out.',
|
|
default=False
|
|
)
|
|
|
|
def _export_for_ui(self, orderline):
|
|
result = super()._export_for_ui(orderline)
|
|
result['is_quotation_line'] = orderline.is_quotation_line
|
|
return result
|
|
|
|
def _order_line_fields(self, line, session_id=None):
|
|
result = super()._order_line_fields(line, session_id)
|
|
if 'is_quotation_line' in line[2]:
|
|
result[2]['is_quotation_line'] = line[2]['is_quotation_line']
|
|
return result
|
|
|