Add insurance template

This commit is contained in:
2026-04-06 17:30:50 +02:00
parent 845b9cf749
commit ec359f6b8a
12 changed files with 1472 additions and 26 deletions

View File

@@ -6,7 +6,7 @@ from trytond.pyson import Bool, Eval, Id
from trytond.model import (ModelSQL, ModelView)
from trytond.tools import is_full_text, lstrip_wildcard
from trytond.transaction import Transaction, inactive_records
from decimal import getcontext, Decimal, ROUND_HALF_UP
from decimal import getcontext, Decimal, ROUND_HALF_UP
from sql.aggregate import Count, Max, Min, Sum, Avg, BoolOr
from sql.conditionals import Case
from sql import Column, Literal
@@ -23,8 +23,10 @@ import io
import base64
import logging
import json
import re
import html
import re
import html
from trytond.exceptions import UserError
from trytond.modules.stock.shipment import SupplierShipping as BaseSupplierShipping
logger = logging.getLogger(__name__)
@@ -387,8 +389,8 @@ class ShipmentWR(ModelSQL,ModelView):
shipment_in = fields.Many2One('stock.shipment.in',"Shipment In")
wr = fields.Many2One('weight.report',"WR")
class ShipmentIn(metaclass=PoolMeta):
__name__ = 'stock.shipment.in'
class ShipmentIn(metaclass=PoolMeta):
__name__ = 'stock.shipment.in'
from_location = fields.Many2One('stock.location', 'From location')
to_location = fields.Many2One('stock.location', 'To location')
@@ -459,9 +461,134 @@ class ShipmentIn(metaclass=PoolMeta):
'send': {},
})
def get_vessel_type(self,name=None):
if self.vessel:
return self.vessel.vessel_type
def get_vessel_type(self,name=None):
if self.vessel:
return self.vessel.vessel_type
def _get_report_primary_move(self):
moves = list(self.incoming_moves or self.moves or [])
return moves[0] if moves else None
def _get_report_primary_lot(self):
move = self._get_report_primary_move()
return getattr(move, 'lot', None) if move else None
def _get_report_trade_line(self):
lot = self._get_report_primary_lot()
if not lot:
return None
return getattr(lot, 'sale_line', None) or getattr(lot, 'line', None)
def _get_report_insurance_fee(self):
for fee in self.fees or []:
product = getattr(fee, 'product', None)
name = ((getattr(product, 'name', '') or '')).strip().lower()
if 'insurance' in name:
return fee
return None
@staticmethod
def _format_report_amount(value):
if value in (None, ''):
return ''
value = Decimal(str(value or 0)).quantize(Decimal('0.01'))
return format(value, 'f')
@property
def report_product_name(self):
line = self._get_report_trade_line()
product = getattr(line, 'product', None) if line else None
if product:
return product.name or ''
move = self._get_report_primary_move()
product = getattr(move, 'product', None) if move else None
return getattr(product, 'name', '') or ''
@property
def report_product_description(self):
line = self._get_report_trade_line()
product = getattr(line, 'product', None) if line else None
if product:
return product.description or ''
move = self._get_report_primary_move()
product = getattr(move, 'product', None) if move else None
return getattr(product, 'description', '') or ''
@property
def report_insurance_footer_ref(self):
return self.bl_number or self.number or ''
@property
def report_insurance_certificate_number(self):
return self.bl_number or self.number or ''
@property
def report_insurance_account_of(self):
line = self._get_report_trade_line()
trade = getattr(line, 'sale', None) or getattr(line, 'purchase', None)
party = getattr(trade, 'party', None) if trade else None
if party:
return party.rec_name or ''
return getattr(self.supplier, 'rec_name', '') or ''
@property
def report_insurance_goods_description(self):
name = self.report_product_name
description = self.report_product_description
if description and description != name:
return ' - '.join(part for part in [name, description] if part)
return name or description
@property
def report_insurance_loading_port(self):
return getattr(self.from_location, 'name', '') or ''
@property
def report_insurance_discharge_port(self):
return getattr(self.to_location, 'name', '') or ''
@property
def report_insurance_transport(self):
if self.vessel and self.vessel.vessel_name:
return self.vessel.vessel_name
return self.transport_type or ''
@property
def report_insurance_amount(self):
fee = self._get_report_insurance_fee()
if not fee:
return ''
currency = getattr(fee, 'currency', None)
currency_text = (
getattr(currency, 'rec_name', None)
or getattr(currency, 'code', None)
or getattr(currency, 'symbol', None)
or '')
amount = self._format_report_amount(fee.get_amount())
return ' '.join(part for part in [currency_text, amount] if part)
@property
def report_insurance_surveyor(self):
if self.controller:
return self.controller.rec_name or ''
fee = self._get_report_insurance_fee()
supplier = getattr(fee, 'supplier', None) if fee else None
return getattr(supplier, 'rec_name', '') or ''
@property
def report_insurance_issue_place_and_date(self):
Date = Pool().get('ir.date')
address = None
if self.company and getattr(self.company, 'party', None):
address = self.company.party.address_get()
place = (
getattr(address, 'city', None)
or getattr(self.company.party, 'rec_name', None)
if self.company and getattr(self.company, 'party', None) else ''
) or ''
today = Date.today()
date_text = today.strftime('%d-%m-%Y') if today else ''
return ', '.join(part for part in [place, date_text] if part)
def get_rec_name(self, name=None):
if self.number:
@@ -1888,7 +2015,7 @@ class Revaluate(Wizard):
return 'end'
class RevaluateStart(ModelView):
class RevaluateStart(ModelView):
"Revaluate"
__name__ = 'account.revaluate.start'
revaluation_date = fields.Date(
@@ -1902,5 +2029,64 @@ class RevaluateStart(ModelView):
return Date.today()
@classmethod
def default_delete_after(cls):
return False
def default_delete_after(cls):
return False
class ShipmentTemplateReportMixin:
@classmethod
def _get_purchase_trade_configuration(cls):
Configuration = Pool().get('purchase_trade.configuration')
configurations = Configuration.search([], limit=1)
return configurations[0] if configurations else None
@classmethod
def _get_action_report_path(cls, action):
if isinstance(action, dict):
return action.get('report') or ''
return getattr(action, 'report', '') or ''
@classmethod
def _resolve_template_path(cls, field_name, default_prefix):
config = cls._get_purchase_trade_configuration()
template = getattr(config, field_name, '') if config else ''
template = (template or '').strip()
if not template:
raise UserError('No template found')
if '/' not in template:
return f'{default_prefix}/{template}'
return template
@classmethod
def _get_resolved_action(cls, action):
report_path = cls._resolve_configured_report_path(action)
if isinstance(action, dict):
resolved = dict(action)
resolved['report'] = report_path
return resolved
setattr(action, 'report', report_path)
return action
@classmethod
def _execute(cls, records, header, data, action):
resolved_action = cls._get_resolved_action(action)
return super()._execute(records, header, data, resolved_action)
class ShipmentShippingReport(ShipmentTemplateReportMixin, BaseSupplierShipping):
__name__ = 'stock.shipment.in.shipping'
@classmethod
def _resolve_configured_report_path(cls, action):
return cls._resolve_template_path(
'shipment_shipping_report_template', 'stock')
class ShipmentInsuranceReport(ShipmentTemplateReportMixin, BaseSupplierShipping):
__name__ = 'stock.shipment.in.insurance'
@classmethod
def _resolve_configured_report_path(cls, action):
return cls._resolve_template_path(
'shipment_insurance_report_template', 'stock')