275 lines
12 KiB
Python
275 lines
12 KiB
Python
# -*- coding: utf-8 -*-
|
|
# Copyright 2020-Today TechKhedut.
|
|
# Part of TechKhedut. See LICENSE file for full copyright and licensing details.
|
|
from odoo import fields, models, api, _
|
|
|
|
|
|
class InternalTransfer(models.Model):
|
|
_name = 'internal.transfer'
|
|
_description = 'Internal transfer material requisition'
|
|
_inherit = ['mail.thread', 'mail.activity.mixin']
|
|
|
|
name = fields.Char(string='Sequence', required=True, readonly=True, default=lambda self: _('New'))
|
|
title = fields.Char(string="Title")
|
|
stage = fields.Selection([('draft', 'Draft'), ('in_progress', 'In Progress'), ('done', 'Done'),
|
|
('cancel', 'Cancel')], default='draft', string="Stage", tracking=True)
|
|
is_order_created = fields.Boolean()
|
|
delivery_order_check = fields.Boolean(compute="_compute_delivery_order_status")
|
|
|
|
# Other Details
|
|
date = fields.Date(string="Date", default=fields.Date.today())
|
|
responsible_id = fields.Many2one('res.users', default=lambda self: self.env.user and self.env.user.id or False,
|
|
string="Created By")
|
|
|
|
# Project Details
|
|
company_id = fields.Many2one('res.company', string="Company", default=lambda self: self.env.company)
|
|
site_id = fields.Many2one('tk.construction.site', string="Project")
|
|
project_id = fields.Many2one('tk.construction.project', string="Sub Project")
|
|
warehouse_id = fields.Many2one(related="site_id.warehouse_id")
|
|
|
|
# Work Type & Phase
|
|
work_type_id = fields.Many2one('job.type', string="Work Type")
|
|
job_sheet_id = fields.Many2one('job.costing', string="Phase(WBS)")
|
|
work_order_id = fields.Many2one('job.order', string="Work Order")
|
|
material_req_id = fields.Many2one('material.requisition', string="Material Requisition")
|
|
|
|
# Internal Transfer & Forward Transfer
|
|
is_forward_transfer = fields.Boolean(tracking=True)
|
|
forward_transfer_id = fields.Many2one('internal.transfer', string="Forward Transfer")
|
|
internal_ref = fields.Char(string="Internal Transfer Ref.")
|
|
|
|
# Department
|
|
department_id = fields.Many2one('construction.department', string="Department")
|
|
manager_ids = fields.Many2many('res.users', string="Manager")
|
|
user_id = fields.Many2one('res.users', string="Responsible User ")
|
|
|
|
# Additional Info
|
|
vehicle_no = fields.Char(string="Vehicle No")
|
|
vehicle_name = fields.Char(string="Name")
|
|
model = fields.Char(string="Model")
|
|
driver_name = fields.Char(string="Driver Name")
|
|
phone = fields.Char(string="Phone")
|
|
|
|
# One 2 many
|
|
internal_line_ids = fields.One2many('internal.transfer.line', 'internal_transfer_id',
|
|
string="Internal Transfer Line")
|
|
|
|
# Count
|
|
delivery_count = fields.Integer(string="Delivery Count", compute="_compute_count")
|
|
|
|
# Create, Write, Unlink, Constrain
|
|
@api.model_create_multi
|
|
def create(self, vals_list):
|
|
for vals in vals_list:
|
|
if vals.get('name', _('New')) == _('New'):
|
|
vals['name'] = self.env['ir.sequence'].next_by_code('internal.transfer') or _('New')
|
|
res = super(InternalTransfer, self).create(vals_list)
|
|
return res
|
|
|
|
def name_get(self):
|
|
data = []
|
|
for rec in self:
|
|
data.append((rec.id, '%s - %s' % (rec.name, rec.title)))
|
|
return data
|
|
|
|
# Compute
|
|
def _compute_count(self):
|
|
for rec in self:
|
|
rec.delivery_count = self.env['stock.picking'].search_count([('transfer_id', '=', rec.id)])
|
|
|
|
# Compute
|
|
@api.depends('internal_line_ids')
|
|
def _compute_delivery_order_status(self):
|
|
delivery = True
|
|
delivery_orders = self.env['stock.picking'].search([('transfer_id', '=', self.id)])
|
|
if delivery_orders:
|
|
for rec in delivery_orders:
|
|
if not rec.state == 'done':
|
|
delivery = False
|
|
break
|
|
else:
|
|
delivery = False
|
|
if delivery:
|
|
self.delivery_order_check = True
|
|
else:
|
|
self.delivery_order_check = False
|
|
|
|
# Onchange
|
|
@api.onchange('department_id', 'manager_ids')
|
|
def _onchange_department_manager(self):
|
|
ids = []
|
|
for rec in self:
|
|
if rec.department_id:
|
|
ids = rec.department_id.manager_ids.ids
|
|
return {'domain': {'manager_ids': [('id', 'in', ids)]}}
|
|
|
|
@api.onchange('department_id', 'manager_ids', 'user_id')
|
|
def _onchange_department_responsible(self):
|
|
ids = []
|
|
for rec in self:
|
|
if rec.department_id:
|
|
ids = rec.department_id.user_ids.ids
|
|
return {'domain': {'user_id': [('id', 'in', ids)]}}
|
|
|
|
# Smart Button
|
|
def action_view_delivery_order(self):
|
|
return {
|
|
'type': 'ir.actions.act_window',
|
|
'name': _('Delivery Orders'),
|
|
'res_model': 'stock.picking',
|
|
'domain': [('transfer_id', '=', self.id)],
|
|
'context': {'default_transfer_id': self.id},
|
|
'view_mode': 'list,form,kanban',
|
|
'target': 'current'
|
|
}
|
|
|
|
# Button
|
|
def action_ready_transfer(self):
|
|
self.stage = 'in_progress'
|
|
self.material_req_id.stage = 'internal_transfer'
|
|
|
|
def action_complete_transfer(self):
|
|
self.material_req_id.stage = 'material_arrived'
|
|
self.work_order_id.state = 'material_arrive'
|
|
self.stage = 'done'
|
|
return {
|
|
'type': 'ir.actions.act_window',
|
|
'name': _('Work Order'),
|
|
'res_model': 'job.order',
|
|
'res_id': self.work_order_id.id,
|
|
'view_mode': 'form',
|
|
'target': 'current'
|
|
}
|
|
|
|
def action_cancel_transfer(self):
|
|
self.material_req_id.stage = 'cancel'
|
|
self.stage = 'cancel'
|
|
|
|
def action_internal_transfer(self):
|
|
pickup_warehouse_ids = self.internal_line_ids.mapped('pickup_warehouse_id').mapped('id')
|
|
delivery_warehouse_ids = self.internal_line_ids.mapped('delivery_warehouse_id').mapped('id')
|
|
for pickup in pickup_warehouse_ids:
|
|
for delivery in delivery_warehouse_ids:
|
|
lines = []
|
|
created_ids = []
|
|
stock_picking_type_id = False
|
|
source_id = False
|
|
destination_id = False
|
|
for line in self.internal_line_ids:
|
|
if line.pickup_warehouse_id.id == pickup and line.delivery_warehouse_id.id == delivery:
|
|
lines.append((0, 0, {
|
|
'product_id': line.product_id.id,
|
|
'product_uom_qty': line.qty,
|
|
'product_uom': line.uom_id.id,
|
|
'location_id': line.pickup_warehouse_id.lot_stock_id.id,
|
|
'location_dest_id': line.delivery_warehouse_id.lot_stock_id.id,
|
|
'name': line.name
|
|
}))
|
|
source_id = line.pickup_warehouse_id.lot_stock_id
|
|
destination_id = line.delivery_warehouse_id.lot_stock_id
|
|
stock_picking_type_id = self.env['stock.picking.type'].search(
|
|
[('code', '=', 'internal'), ('warehouse_id', '=', line.pickup_warehouse_id.id)], limit=1)
|
|
created_ids.append(line.id)
|
|
if lines and stock_picking_type_id and source_id and destination_id:
|
|
delivery_record = {
|
|
'picking_type_id': stock_picking_type_id.id,
|
|
'location_id': source_id.id,
|
|
'location_dest_id': destination_id.id,
|
|
'move_ids_without_package': lines,
|
|
'transfer_id': self.id,
|
|
'move_type': 'one'
|
|
}
|
|
delivery_id = self.env['stock.picking'].create(delivery_record)
|
|
delivery_id.action_confirm()
|
|
for data in created_ids:
|
|
internal_line_id = self.env['internal.transfer.line'].browse(data)
|
|
internal_line_id.delivery_order_id = delivery_id.id
|
|
self.material_req_id.internal_transfer_id = self.id
|
|
self.is_order_created = True
|
|
|
|
def action_forward_transfer(self):
|
|
is_any_forward = False
|
|
for data in self.internal_line_ids:
|
|
if data.delivery_warehouse_id.id == self.warehouse_id.id:
|
|
is_any_forward = True
|
|
if not is_any_forward:
|
|
message = {
|
|
'type': 'ir.actions.client',
|
|
'tag': 'display_notification',
|
|
'params': {
|
|
'type': 'info',
|
|
'message': "There are no any forward transfer in Internal transfer",
|
|
'sticky': False,
|
|
}
|
|
}
|
|
return message
|
|
if is_any_forward:
|
|
internal_record = {
|
|
'title': self.title,
|
|
'site_id': self.site_id.id,
|
|
'project_id': self.project_id.id,
|
|
'work_type_id': self.work_type_id.id,
|
|
'job_sheet_id': self.job_sheet_id.id,
|
|
'work_order_id': self.work_order_id.id,
|
|
'material_req_id': self.material_req_id.id,
|
|
'company_id': self.company_id.id,
|
|
'department_id': self.department_id.id,
|
|
'manager_ids': self.manager_ids.ids,
|
|
'user_id': self.user_id.id,
|
|
'stage': 'in_progress',
|
|
'internal_ref': self.name
|
|
}
|
|
internal_transfer_id = self.env['internal.transfer'].create(internal_record)
|
|
for data in self.internal_line_ids:
|
|
if data.delivery_warehouse_id.id == self.warehouse_id.id:
|
|
line_record = {
|
|
'sub_category_id': data.sub_category_id.id,
|
|
'product_id': data.product_id.id,
|
|
'name': data.name,
|
|
'qty': data.qty,
|
|
'pickup_warehouse_id': data.delivery_warehouse_id.id,
|
|
'delivery_warehouse_id': data.building_id.warehouse_id.id,
|
|
'internal_transfer_id': internal_transfer_id.id
|
|
}
|
|
self.env['internal.transfer.line'].create(line_record)
|
|
self.forward_transfer_id = internal_transfer_id.id
|
|
internal_transfer_id.is_forward_transfer = True
|
|
return {
|
|
'type': 'ir.actions.act_window',
|
|
'name': _('Forward Transfer'),
|
|
'res_model': 'internal.transfer',
|
|
'res_id': internal_transfer_id.id,
|
|
'view_mode': 'form',
|
|
'target': 'current'
|
|
}
|
|
|
|
|
|
class InternalTransferLine(models.Model):
|
|
_name = 'internal.transfer.line'
|
|
_description = "Internal Transfer Line"
|
|
|
|
product_id = fields.Many2one('product.product', string="Product")
|
|
name = fields.Char(string="Description")
|
|
qty = fields.Integer('Qty.')
|
|
forcast_qty = fields.Char(string="Forecast Qty.", compute="_compute_forcast_qty")
|
|
uom_id = fields.Many2one(related="product_id.uom_po_id", string="UOM")
|
|
pickup_warehouse_id = fields.Many2one('stock.warehouse', string="Pickup Warehouse")
|
|
delivery_warehouse_id = fields.Many2one('stock.warehouse', string="Delivery Warehouse")
|
|
internal_transfer_id = fields.Many2one('internal.transfer', string="Internal Transfer")
|
|
delivery_order_id = fields.Many2one('stock.picking', string="Do")
|
|
state = fields.Selection(related="delivery_order_id.state", string="Status")
|
|
sub_category_id = fields.Many2one('job.sub.category', string="Work Sub Type")
|
|
|
|
@api.depends('pickup_warehouse_id', 'product_id')
|
|
def _compute_forcast_qty(self):
|
|
for rec in self:
|
|
qty = 0.0
|
|
if rec.product_id:
|
|
qty = rec.product_id.with_context(warehouse=rec.pickup_warehouse_id.id).virtual_available
|
|
rec.forcast_qty = qty
|
|
|
|
@api.onchange('product_id')
|
|
def _onchange_product_desc(self):
|
|
for rec in self:
|
|
rec.name = rec.product_id.name
|