# -*- 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