pos_reverse_downpayment/models/pos_order.py
2026-02-27 17:58:49 +07:00

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