This commit is contained in:
2026-05-24 19:04:58 +02:00
parent a22d185fb0
commit 20f51de50f
7 changed files with 380 additions and 1 deletions

View File

@@ -74,6 +74,10 @@ def register():
ctrm_reporting.CTRMPnlDimensionContext,
ctrm_reporting.CTRMCreditRisk,
ctrm_reporting.CTRMCreditRiskContext,
ctrm_reporting.CTRMShippingLogistics,
ctrm_reporting.CTRMShippingLogisticsContext,
ctrm_reporting.CTRMInventory,
ctrm_reporting.CTRMInventoryContext,
configuration.Configuration,
pricing.ImportPricesStart,
pricing.ImportPricesResult,

View File

@@ -1,5 +1,5 @@
from sql import Literal, Null, Window
from sql.aggregate import Max, Min, Sum
from sql.aggregate import Count, Max, Min, Sum
from sql.conditionals import Case, Coalesce
from sql.functions import CurrentTimestamp, RowNumber
@@ -896,3 +896,267 @@ class CTRMCreditRisk(ModelSQL, ModelView):
party.risk_level.as_('risk_level'),
status.as_('status'),
where=where))
class CTRMShippingLogisticsContext(ModelView):
"CTRM Shipping Logistics Context"
__name__ = 'ctrm.reporting.operations.shipping.context'
from_date = fields.Date("From Date")
to_date = fields.Date("To Date")
supplier = fields.Many2One('party.party', "Supplier")
warehouse = fields.Many2One('stock.location', "Warehouse")
transport_type = fields.Selection([
(None, ''),
('vessel', 'Vessel'),
('truck', 'Truck'),
('other', 'Other'),
], "Transport Type")
vessel = fields.Many2One('trade.vessel', "Vessel")
state = fields.Char("State")
class CTRMShippingLogistics(ModelSQL, ModelView):
"CTRM Shipping Logistics"
__name__ = 'ctrm.reporting.operations.shipping'
shipment = fields.Many2One('stock.shipment.in', "Shipment")
reference = fields.Char("Reference")
supplier = fields.Many2One('party.party', "Supplier")
warehouse = fields.Many2One('stock.location', "Warehouse")
from_location = fields.Many2One('stock.location', "From")
to_location = fields.Many2One('stock.location', "To")
transport_type = fields.Selection([
(None, ''),
('vessel', 'Vessel'),
('truck', 'Truck'),
('other', 'Other'),
], "Transport Type")
vessel = fields.Many2One('trade.vessel', "Vessel")
state = fields.Char("State")
planned_date = fields.Date("Planned Date")
effective_date = fields.Date("Effective Date")
estimated_loading = fields.Date("Estimated Loading")
eta_pol = fields.Date("ETA POL")
eta = fields.Date("ETA")
etd = fields.Date("ETD")
discharged_date = fields.Date("Discharged Date")
booking = fields.Char("Booking")
bl_number = fields.Char("BL Number")
product = fields.Many2One('product.product', "Product")
quantity = fields.Numeric("Quantity", digits=(16, 5))
unit = fields.Many2One('product.uom', "Unit")
lot_count = fields.Integer("Lots")
@classmethod
def table_query(cls):
ShipmentIn = Pool().get('stock.shipment.in')
Lot = Pool().get('lot.lot')
shipment = ShipmentIn.__table__()
lot = Lot.__table__()
lot_query = lot.select(
lot.lot_shipment_in.as_('shipment'),
Count(lot.id).as_('lot_count'),
Sum(Coalesce(lot.lot_qt, 0)).as_('quantity'),
Max(lot.lot_product).as_('product'),
Max(lot.lot_unit_line).as_('unit'),
where=((lot.lot_shipment_in != Null)
& (lot.lot_type == 'physic')),
group_by=[lot.lot_shipment_in])
context = Transaction().context
logistics_date = Coalesce(
shipment.etad, shipment.eta, shipment.planned_date)
where = shipment.id != Null
if context.get('from_date'):
where &= logistics_date >= context['from_date']
if context.get('to_date'):
where &= logistics_date <= context['to_date']
if context.get('supplier'):
where &= shipment.supplier == context['supplier']
if context.get('warehouse'):
where &= shipment.warehouse == context['warehouse']
if context.get('transport_type'):
where &= shipment.transport_type == context['transport_type']
if context.get('vessel'):
where &= shipment.vessel == context['vessel']
if context.get('state'):
where &= shipment.state == context['state']
return (
shipment
.join(lot_query, 'LEFT',
condition=lot_query.shipment == shipment.id)
.select(
Literal(0).as_('create_uid'),
CurrentTimestamp().as_('create_date'),
Literal(None).as_('write_uid'),
Literal(None).as_('write_date'),
shipment.id.as_('id'),
shipment.id.as_('shipment'),
shipment.ref.as_('reference'),
shipment.supplier.as_('supplier'),
shipment.warehouse.as_('warehouse'),
shipment.from_location.as_('from_location'),
shipment.to_location.as_('to_location'),
shipment.transport_type.as_('transport_type'),
shipment.vessel.as_('vessel'),
shipment.state.as_('state'),
shipment.planned_date.as_('planned_date'),
shipment.effective_date.as_('effective_date'),
shipment.etl.as_('estimated_loading'),
shipment.eta.as_('eta_pol'),
shipment.etad.as_('eta'),
shipment.etd.as_('etd'),
shipment.unloaded.as_('discharged_date'),
shipment.booking.as_('booking'),
shipment.bl_number.as_('bl_number'),
lot_query.product.as_('product'),
Coalesce(lot_query.quantity, 0).as_('quantity'),
lot_query.unit.as_('unit'),
Coalesce(lot_query.lot_count, 0).as_('lot_count'),
where=where))
class CTRMInventoryContext(ModelView):
"CTRM Inventory Context"
__name__ = 'ctrm.reporting.operations.inventory.context'
product = fields.Many2One('product.product', "Product")
supplier = fields.Many2One('party.party', "Supplier")
client = fields.Many2One('party.party', "Client")
warehouse = fields.Many2One('stock.location', "Warehouse")
lot_status = fields.Selection([
(None, ''),
('forecast', 'Forecast'),
('loading', 'Loading'),
('transit', 'Transit'),
('destination', 'Destination'),
('stock', 'Stock'),
('delivered', 'Delivered'),
], "Status")
availability = fields.Selection([
(None, ''),
('available', 'Available'),
('reserved', 'Reserved'),
('locked', 'Locked'),
('prov', 'Prov. inv'),
('invoiced', 'Invoiced'),
], "Availability")
class CTRMInventory(ModelSQL, ModelView):
"CTRM Inventory"
__name__ = 'ctrm.reporting.operations.inventory'
lot = fields.Many2One('lot.lot', "Lot")
product = fields.Many2One('product.product', "Product")
supplier = fields.Many2One('party.party', "Supplier")
client = fields.Many2One('party.party', "Client")
purchase = fields.Many2One('purchase.purchase', "Purchase")
purchase_line = fields.Many2One('purchase.line', "Purchase Line")
sale = fields.Many2One('sale.sale', "Sale")
sale_line = fields.Many2One('sale.line', "Sale Line")
lot_status = fields.Selection([
(None, ''),
('forecast', 'Forecast'),
('loading', 'Loading'),
('transit', 'Transit'),
('destination', 'Destination'),
('stock', 'Stock'),
('delivered', 'Delivered'),
], "Status")
availability = fields.Selection([
(None, ''),
('available', 'Available'),
('reserved', 'Reserved'),
('locked', 'Locked'),
('prov', 'Prov. inv'),
('invoiced', 'Invoiced'),
], "Availability")
warehouse = fields.Many2One('stock.location', "Warehouse")
from_location = fields.Many2One('stock.location', "From")
to_location = fields.Many2One('stock.location', "To")
shipment_in = fields.Many2One('stock.shipment.in', "Shipment In")
shipment_out = fields.Many2One('stock.shipment.out', "Shipment Out")
shipment_internal = fields.Many2One(
'stock.shipment.internal', "Shipment Internal")
container = fields.Char("Container")
quantity = fields.Numeric("Quantity", digits=(16, 5))
unit = fields.Many2One('product.uom', "Unit")
@classmethod
def table_query(cls):
pool = Pool()
Lot = pool.get('lot.lot')
PurchaseLine = pool.get('purchase.line')
Purchase = pool.get('purchase.purchase')
SaleLine = pool.get('sale.line')
Sale = pool.get('sale.sale')
ShipmentIn = pool.get('stock.shipment.in')
lot = Lot.__table__()
purchase_line = PurchaseLine.__table__()
purchase = Purchase.__table__()
sale_line = SaleLine.__table__()
sale = Sale.__table__()
shipment_in = ShipmentIn.__table__()
context = Transaction().context
warehouse = shipment_in.warehouse
from_location = shipment_in.from_location
to_location = shipment_in.to_location
where = lot.lot_type == 'physic'
if context.get('product'):
where &= lot.lot_product == context['product']
if context.get('supplier'):
where &= purchase.party == context['supplier']
if context.get('client'):
where &= sale.party == context['client']
if context.get('warehouse'):
where &= warehouse == context['warehouse']
if context.get('lot_status'):
where &= lot.lot_status == context['lot_status']
if context.get('availability'):
where &= lot.lot_av == context['availability']
return (
lot
.join(purchase_line, 'LEFT',
condition=lot.line == purchase_line.id)
.join(purchase, 'LEFT',
condition=purchase_line.purchase == purchase.id)
.join(sale_line, 'LEFT',
condition=lot.sale_line == sale_line.id)
.join(sale, 'LEFT',
condition=sale_line.sale == sale.id)
.join(shipment_in, 'LEFT',
condition=lot.lot_shipment_in == shipment_in.id)
.select(
Literal(0).as_('create_uid'),
CurrentTimestamp().as_('create_date'),
Literal(None).as_('write_uid'),
Literal(None).as_('write_date'),
lot.id.as_('id'),
lot.id.as_('lot'),
lot.lot_product.as_('product'),
purchase.party.as_('supplier'),
sale.party.as_('client'),
purchase.id.as_('purchase'),
lot.line.as_('purchase_line'),
sale.id.as_('sale'),
lot.sale_line.as_('sale_line'),
lot.lot_status.as_('lot_status'),
lot.lot_av.as_('availability'),
warehouse.as_('warehouse'),
from_location.as_('from_location'),
to_location.as_('to_location'),
lot.lot_shipment_in.as_('shipment_in'),
lot.lot_shipment_out.as_('shipment_out'),
lot.lot_shipment_internal.as_('shipment_internal'),
lot.lot_container.as_('container'),
Coalesce(lot.lot_qt, 0).as_('quantity'),
lot.lot_unit_line.as_('unit'),
where=where))

View File

@@ -160,6 +160,46 @@
<field name="view" ref="ctrm_credit_risk_view_list"/>
<field name="act_window" ref="act_ctrm_credit_risk"/>
</record>
<record model="ir.ui.view" id="ctrm_shipping_logistics_context_view_form">
<field name="model">ctrm.reporting.operations.shipping.context</field>
<field name="type">form</field>
<field name="name">ctrm_shipping_logistics_context_form</field>
</record>
<record model="ir.ui.view" id="ctrm_shipping_logistics_view_list">
<field name="model">ctrm.reporting.operations.shipping</field>
<field name="type">tree</field>
<field name="name">ctrm_shipping_logistics_list</field>
</record>
<record model="ir.action.act_window" id="act_ctrm_shipping_logistics">
<field name="name">Shipping Logistics</field>
<field name="res_model">ctrm.reporting.operations.shipping</field>
<field name="context_model">ctrm.reporting.operations.shipping.context</field>
</record>
<record model="ir.action.act_window.view" id="act_ctrm_shipping_logistics_view">
<field name="sequence" eval="10"/>
<field name="view" ref="ctrm_shipping_logistics_view_list"/>
<field name="act_window" ref="act_ctrm_shipping_logistics"/>
</record>
<record model="ir.ui.view" id="ctrm_inventory_context_view_form">
<field name="model">ctrm.reporting.operations.inventory.context</field>
<field name="type">form</field>
<field name="name">ctrm_inventory_context_form</field>
</record>
<record model="ir.ui.view" id="ctrm_inventory_view_list">
<field name="model">ctrm.reporting.operations.inventory</field>
<field name="type">tree</field>
<field name="name">ctrm_inventory_list</field>
</record>
<record model="ir.action.act_window" id="act_ctrm_inventory">
<field name="name">Inventory</field>
<field name="res_model">ctrm.reporting.operations.inventory</field>
<field name="context_model">ctrm.reporting.operations.inventory.context</field>
</record>
<record model="ir.action.act_window.view" id="act_ctrm_inventory_view">
<field name="sequence" eval="10"/>
<field name="view" ref="ctrm_inventory_view_list"/>
<field name="act_window" ref="act_ctrm_inventory"/>
</record>
<menuitem
name="Positions"
@@ -262,11 +302,13 @@
name="Shipping Logistics"
parent="menu_ctrm_operations"
sequence="10"
action="act_ctrm_shipping_logistics"
id="menu_ctrm_operations_shipping"/>
<menuitem
name="Inventory"
parent="menu_ctrm_operations"
sequence="20"
action="act_ctrm_inventory"
id="menu_ctrm_operations_inventory"/>
<menuitem
name="Contract Performance"

View File

@@ -0,0 +1,14 @@
<form>
<label name="product"/>
<field name="product"/>
<label name="warehouse"/>
<field name="warehouse"/>
<label name="supplier"/>
<field name="supplier"/>
<label name="client"/>
<field name="client"/>
<label name="lot_status"/>
<field name="lot_status"/>
<label name="availability"/>
<field name="availability"/>
</form>

View File

@@ -0,0 +1,19 @@
<tree>
<field name="lot" width="140"/>
<field name="product" width="160"/>
<field name="supplier"/>
<field name="client"/>
<field name="lot_status"/>
<field name="availability"/>
<field name="warehouse"/>
<field name="from_location"/>
<field name="to_location"/>
<field name="shipment_in"/>
<field name="shipment_out"/>
<field name="shipment_internal"/>
<field name="container"/>
<field name="quantity" sum="1"/>
<field name="unit"/>
<field name="purchase"/>
<field name="sale"/>
</tree>

View File

@@ -0,0 +1,16 @@
<form>
<label name="from_date"/>
<field name="from_date"/>
<label name="to_date"/>
<field name="to_date"/>
<label name="supplier"/>
<field name="supplier"/>
<label name="warehouse"/>
<field name="warehouse"/>
<label name="transport_type"/>
<field name="transport_type"/>
<label name="vessel"/>
<field name="vessel"/>
<label name="state"/>
<field name="state"/>
</form>

View File

@@ -0,0 +1,20 @@
<tree>
<field name="shipment" width="140"/>
<field name="reference"/>
<field name="supplier" width="160"/>
<field name="warehouse"/>
<field name="transport_type"/>
<field name="vessel"/>
<field name="state"/>
<field name="estimated_loading"/>
<field name="eta_pol"/>
<field name="eta"/>
<field name="etd"/>
<field name="discharged_date"/>
<field name="booking"/>
<field name="bl_number"/>
<field name="product"/>
<field name="quantity" sum="1"/>
<field name="unit"/>
<field name="lot_count" sum="1"/>
</tree>