This commit is contained in:
gsinghpal
2026-05-18 22:33:23 -04:00
parent 25f568f225
commit 091f98e1f9
76 changed files with 4521 additions and 220 deletions

View File

@@ -5,7 +5,7 @@
{
'name': 'Fusion Plating — Logistics',
'version': '19.0.3.8.0',
'version': '19.0.3.9.0',
'category': 'Manufacturing/Plating',
'summary': (
'Pickup & delivery for plating shops: vehicle master, driver '
@@ -43,6 +43,7 @@ Copyright (c) 2026 Nexa Systems Inc. All rights reserved.
'fusion_plating',
'fusion_plating_configurator',
'fusion_plating_receiving', # Shared "Shipping & Receiving" menu root
'fusion_shipping',
'hr',
'mail',
],

View File

@@ -123,6 +123,86 @@ class FpDelivery(models.Model):
'ir.attachment',
string='Packing List',
)
# ---- Phase A — outbound carrier + shipment link ----------------------
# Mirrors the fields on fp.receiving. Populated by
# fp.job._fp_create_delivery from the linked receiving when this
# delivery is auto-created on job-done; shipping crew can override
# at ship time.
x_fc_carrier_id = fields.Many2one(
'delivery.carrier', string='Outbound Carrier', tracking=True,
ondelete='set null',
help='Carrier picked at receiving time; can be overridden by '
'the shipping crew before issuing the label.',
)
x_fc_outbound_shipment_id = fields.Many2one(
'fusion.shipment', string='Outbound Shipment', tracking=True,
ondelete='set null',
copy=False,
help='The shipment record carrying weight, dimensions, label '
'PDF, and tracking. Usually the same shipment that was '
'created at receiving time.',
)
x_fc_outbound_shipment_count = fields.Integer(
compute='_compute_x_fc_outbound_shipment_count',
)
@api.depends('x_fc_outbound_shipment_id')
def _compute_x_fc_outbound_shipment_count(self):
for rec in self:
rec.x_fc_outbound_shipment_count = (
1 if rec.x_fc_outbound_shipment_id else 0
)
@api.onchange('x_fc_carrier_id')
def _onchange_x_fc_carrier_id(self):
for rec in self:
ship = rec.x_fc_outbound_shipment_id
if ship and ship.status == 'draft' and rec.x_fc_carrier_id:
ship.carrier_id = rec.x_fc_carrier_id.id
def action_create_outbound_shipment(self):
self.ensure_one()
if self.x_fc_outbound_shipment_id:
return self.action_view_outbound_shipment()
if 'fusion.shipment' not in self.env:
raise UserError(_(
'fusion_shipping module is not installed. '
'Cannot create an outbound shipment.'
))
SO = self.env['sale.order'].sudo()
so = False
if self.job_ref:
Job = self.env.get('fp.job')
if Job is not None:
job = Job.sudo().search(
[('name', '=', self.job_ref)], limit=1,
)
so = job.sale_order_id if job else False
vals = {
'sale_order_id': so.id if so else False,
'carrier_id': self.x_fc_carrier_id.id if self.x_fc_carrier_id else False,
'status': 'draft',
}
shipment = self.env['fusion.shipment'].sudo().create(vals)
self.x_fc_outbound_shipment_id = shipment.id
self.message_post(body=_(
'Outbound shipment <b>%s</b> created (draft).'
) % shipment.name)
return self.action_view_outbound_shipment()
def action_view_outbound_shipment(self):
self.ensure_one()
if not self.x_fc_outbound_shipment_id:
return False
return {
'type': 'ir.actions.act_window',
'name': self.x_fc_outbound_shipment_id.name,
'res_model': 'fusion.shipment',
'res_id': self.x_fc_outbound_shipment_id.id,
'view_mode': 'form',
'target': 'current',
}
state = fields.Selection(
[
('draft', 'Draft'),

View File

@@ -0,0 +1,2 @@
# -*- coding: utf-8 -*-
from . import test_delivery_shipping_fields

View File

@@ -0,0 +1,25 @@
# -*- coding: utf-8 -*-
# Copyright 2026 Nexa Systems Inc.
# License OPL-1 (Odoo Proprietary License v1.0)
"""Phase A — mirror carrier + outbound shipment fields on fp.delivery."""
from odoo.tests.common import TransactionCase
class TestDeliveryShippingFields(TransactionCase):
@classmethod
def setUpClass(cls):
super().setUpClass()
cls.partner = cls.env['res.partner'].create({'name': 'ShipCust'})
def test_carrier_id_field_exists_on_delivery(self):
delivery = self.env['fusion.plating.delivery'].create({
'partner_id': self.partner.id,
})
self.assertIn('x_fc_carrier_id', delivery._fields)
def test_outbound_shipment_id_field_exists_on_delivery(self):
delivery = self.env['fusion.plating.delivery'].create({
'partner_id': self.partner.id,
})
self.assertIn('x_fc_outbound_shipment_id', delivery._fields)

View File

@@ -59,6 +59,16 @@
statusbar_visible="draft,scheduled,en_route,delivered"/>
</header>
<sheet>
<div class="oe_button_box" name="button_box">
<button name="action_create_outbound_shipment"
type="object"
class="oe_stat_button"
icon="fa-truck">
<field name="x_fc_outbound_shipment_count"
widget="statinfo"
string="Outbound Shipment"/>
</button>
</div>
<div class="oe_title">
<label for="name"/>
<h1><field name="name" readonly="1"/></h1>
@@ -84,7 +94,9 @@
<field name="vehicle_id"/>
<field name="tdg_required" widget="boolean_toggle"/>
</group>
<group string="Documents">
<group string="Outbound Shipping">
<field name="x_fc_carrier_id"
options="{'no_create': True}"/>
<field name="coc_attachment_id"/>
<field name="packing_list_attachment_id"/>
<field name="pod_id" readonly="1"/>