from odoo import models, api, fields from odoo.exceptions import AccessError, UserError, ValidationError from datetime import timedelta, date import logging from markupsafe import escape as html_escape _logger = logging.getLogger(__name__) class ShipmentGroup(models.Model): _name = "shipment.group" _description = "Shipment Group" _inherit = ['mail.thread'] _rec_name = 'number' number = fields.Char(string='Document No', index=True, copy=False, readonly=True, tracking=True) shipment_line = fields.One2many('shipment.group.line', 'shipment_id', string='Shipment Group Lines', auto_join=True) partner_id = fields.Many2one('res.partner', string='Customer') carrier_id = fields.Many2one('delivery.carrier', string='Ekspedisi') total_colly_line = fields.Float(string='Total Colly', compute='_compute_total_colly_line') is_multi_partner = fields.Boolean(string='Is Multi Partner', compute='_compute_is_multi_partner') partner_ids = fields.Many2many('res.partner', string='Customers', compute='_compute_partner_ids') driver = fields.Text(string='Driver') @api.depends('shipment_line.partner_id') def _compute_partner_ids(self): for rec in self: rec.partner_ids = rec.shipment_line.mapped('partner_id').ids @api.depends('shipment_line.partner_id') def _compute_is_multi_partner(self): for rec in self: partners = rec.shipment_line.mapped('partner_id') rec.is_multi_partner = len(partners) > 1 def sync_api_shipping(self): for rec in self.shipment_line: picking_names = [lines.picking_id.name for lines in self.shipment_line] if rec.shipment_id.carrier_id.id == 173: rec.picking_id.action_get_kgx_pod( shipment=f"{self.number}" ) elif rec.shipment_id.carrier_id.id == 151: rec.picking_id.track_envio_shipment(shipment=f"{self.number}") @api.depends('shipment_line.total_colly') def _compute_total_colly_line(self): for rec in self: rec.total_colly_line = sum(rec.shipment_line.mapped('total_colly')) @api.model def create(self, vals): vals['number'] = self.env['ir.sequence'].next_by_code('shipment.group') or '0' result = super(ShipmentGroup, self).create(vals) if result.shipment_line and result.shipment_line[0].partner_id: result.partner_id = result.shipment_line[0].partner_id.id return result class ShipmentGroupLine(models.Model): _name = 'shipment.group.line' _description = 'Shipment Group Line' _order = 'shipment_id, id' shipment_id = fields.Many2one('shipment.group', string='Shipment Ref', required=True, ondelete='cascade', index=True, copy=False) partner_id = fields.Many2one('res.partner', string='Customer') picking_id = fields.Many2one('stock.picking', string='Picking') sale_id = fields.Many2one('sale.order', string='Sale Order') state = fields.Char(string='Status', readonly=True, compute='_compute_state') shipping_paid_by = fields.Selection([ ('indoteknik', 'Indoteknik'), ('customer', 'Customer') ], string='Shipping Paid by', copy=False) total_colly = fields.Float(string='Total Colly') carrier_id = fields.Many2one('delivery.carrier', string='Ekspedisi') @api.constrains('picking_id') def _check_picking_id(self): for rec in self: if not rec.picking_id: continue duplicates = self.env['shipment.group.line'].search([ ('picking_id', '=', rec.picking_id.id), ('id', '!=', rec.id) ]) if duplicates: shipment_numbers = duplicates.mapped('shipment_id.number') raise UserError( f"Picking {rec.picking_id.name} sudah discan dalam shipment group berikut: {', '.join(shipment_numbers)}! " "Satu picking hanya boleh dimasukkan dalam satu shipment group." ) @api.depends('picking_id.state') def _compute_state(self): for rec in self: if rec.picking_id: if rec.picking_id.state == 'assigned': rec.state = 'Ready' elif rec.picking_id.state == 'done': rec.state = 'Done' elif rec.picking_id.state == 'cancel': rec.state = 'Cancelled' elif rec.picking_id.state == 'confirmed': rec.state = 'Waiting' elif rec.picking_id.state == 'waiting': rec.state = 'Waiting Another Operation' else: rec.state = 'draft' else: rec.state = 'draft' @api.onchange('picking_id') def onchange_picking_id(self): if self.picking_id: picking = self.picking_id if self.shipment_id.carrier_id and self.shipment_id.carrier_id != picking.carrier_id: raise UserError('carrier must be same as shipment group') if picking.total_mapping_koli == 0: raise UserError(f'Picking {picking.name} tidak memiliki mapping koli') self.partner_id = picking.partner_id self.shipping_paid_by = picking.sale_id.shipping_paid_by self.carrier_id = picking.carrier_id.id self.total_colly = picking.total_mapping_koli if not self.shipment_id.carrier_id: self.shipment_id.carrier_id = picking.carrier_id self.sale_id = picking.sale_id if self.shipment_id: self.shipment_id._compute_is_multi_partner() @api.model def create(self, vals): record = super(ShipmentGroupLine, self).create(vals) if record.picking_id: record.onchange_picking_id() return record def write(self, vals): res = super(ShipmentGroupLine, self).write(vals) if 'picking_id' in vals: self.onchange_picking_id() return res