from odoo import models, fields, api, _ from odoo.exceptions import UserError import base64 from types import SimpleNamespace from odoo.tools import formatLang class PosOrder(models.Model): _inherit = "pos.order" def action_print_backend_ticket(self): self.ensure_one() if self.state not in ("paid", "done", "invoiced"): raise UserError( _( "Solo se puede imprimir el ticket cuando el pedido está pagado o cerrado." ) ) return self.env.ref( "pos_order_backend_receipt.action_report_pos_order_ticket" ).report_action(self) # ----------------- Helpers Backend Ticket ----------------- def _get_backend_tax_breakdown(self): """Return list of dicts with tax_rate, base, amount for legal breakdown. Group by tax (percentage). Only sales taxes (positive or negative based on sign). """ self.ensure_one() breakdown = [] Tax = self.env["account.tax"] currency = self.pricelist_id.currency_id or self.company_id.currency_id # aggregate via line taxes after fiscal position tax_map = {} for line in self.lines: # price_subtotal (sin impuestos), price_subtotal_incl (con impuestos) base = line.price_subtotal tax_amount_line = line.price_subtotal_incl - line.price_subtotal # Derivar tipo (promedio) desde los impuestos aplicados for tax in line.tax_ids_after_fiscal_position: key = tax.id entry = tax_map.setdefault( key, { "tax": tax, "base": 0.0, "amount": 0.0, }, ) # prorratear base / importe cuando múltiples impuestos # simplificación: si hay varios impuestos no compuestos, se reparte proporcional a sus montos teóricos if line.tax_ids_after_fiscal_position: # compute_all para repartir preciso taxes_res = tax.compute_all( line.price_unit * (1 - (line.discount or 0.0) / 100.0), currency, line.qty, product=line.product_id, partner=self.partner_id, ) # encontrar este tax for tline in taxes_res["taxes"]: if tline["id"] == tax.id: entry["amount"] += tline["amount"] # base para ese impuesto específico entry["base"] += tline["base"] else: entry["base"] += base entry["amount"] += tax_amount_line # formatear for v in tax_map.values(): tax = v["tax"] rate = tax.amount if tax.amount_type == "percent" else 0.0 breakdown.append( { "rate": rate, "base": currency.round(v["base"]), "amount": currency.round(v["amount"]), } ) # ordenar por tasa breakdown.sort(key=lambda x: x["rate"]) return breakdown