Tower: upload tk_construction_management 18.0.2.0.8 (was 18.0.2.0.8, via marketplace)

This commit is contained in:
2026-05-08 19:20:12 +00:00
parent c412640ca2
commit 63c62699f5
174 changed files with 44759 additions and 0 deletions

View File

@@ -0,0 +1,813 @@
# -*- coding: utf-8 -*-
# Copyright 2020-Today TechKhedut.
# Part of TechKhedut. See LICENSE file for full copyright and licensing details.
from odoo import api, fields, models, _
from odoo.exceptions import ValidationError
class EquipmentSubcontract(models.Model):
_name = 'equipment.subcontract'
_description = "Equipment Subcontract"
_rec_name = 'seq'
seq = fields.Char(string='Sequence', required=True, readonly=True, default=lambda self: _('New'))
name = fields.Char(string="Title")
equipment_id = fields.Many2one('product.product', string="Equipment", domain="[('is_equipment','=',True)]")
company_id = fields.Many2one('res.company', string='Company', default=lambda self: self.env.company)
currency_id = fields.Many2one('res.currency', related='company_id.currency_id', string='Currency')
cost_type = fields.Selection([('depreciation_cost', 'Depreciation Cost'),
('investment_cost', 'Investment/Interest Cost'),
('tax', 'Tax'),
('rent', 'Rent'),
('other', 'Other')], string="Type ", default='rent')
cost = fields.Monetary(string="Estimation Cost")
vendor_id = fields.Many2one('res.partner', string="Vendor")
purchase_order_id = fields.Many2one('purchase.order', string="Purchase Order")
job_type_id = fields.Many2one('job.type', string="Work Type")
sub_category_id = fields.Many2one('job.sub.category', string="Work Sub Type")
stage = fields.Selection([('draft', 'Draft'), ('in_progress', 'In Progress'), ('done', 'Done')], default='draft')
po_bill = fields.Selection([('bill', 'Bill'), ('purchase_order', 'Purchase Order')], string="Type", default='bill')
ra_bill_ids = fields.One2many('equip.contract.line', 'contract_id', string="Ra Bills")
completion_date = fields.Date(string="Completion Date", compute="compute_completion_date")
# Calculation
qty = fields.Integer(string="Qty.", default=1)
remain_qty = fields.Integer(string="Remaining Qty")
total_cost = fields.Monetary(string="Total Cost")
remaining_amount = fields.Monetary(string="Remaining Amount")
progress = fields.Float(string="Complete Billing", compute="_compute_payment_progress")
tax_id = fields.Many2one('account.tax', string='Tax')
# Project Details
job_order_id = fields.Many2one('job.order', string="Work Order")
phase_id = fields.Many2one(related="job_order_id.job_sheet_id", string="Project Phase(WBS)", store=True)
project_id = fields.Many2one(related='job_order_id.project_id', string="Sub Project", store=True)
task_id = fields.Many2one(related="job_order_id.task_id", string="Task", store=True)
# Department
department_id = fields.Many2one(related="job_order_id.department_id", string="Department", store=True)
manager_ids = fields.Many2many('res.users', store=True, string="Manager")
user_id = fields.Many2one(related="job_order_id.user_id", string="Responsible")
@api.model_create_multi
def create(self, vals_list):
for vals in vals_list:
if vals.get('seq', _('New')) == _('New'):
vals['seq'] = self.env['ir.sequence'].next_by_code('equip.sub') or _('New')
res = super(EquipmentSubcontract, self).create(vals_list)
return res
def action_in_progress(self):
self.stage = 'in_progress'
def action_state_done(self):
self.stage = 'done'
@api.constrains('ra_bill_ids', 'qty')
def _check_ra_bill_qty(self):
qty = 0
for record in self.ra_bill_ids:
if record.qc_status != 'reject':
qty = qty + record.qty
if qty > self.qty:
raise ValidationError(_("Quantity should be less than total qty."))
@api.depends('total_cost', 'remaining_amount')
def _compute_payment_progress(self):
for rec in self:
progress = 0.0
if rec.total_cost and rec.remaining_amount:
progress = (rec.remaining_amount * 100) / rec.total_cost
rec.progress = 100 - progress
@api.depends('stage', 'ra_bill_ids')
def compute_completion_date(self):
for rec in self:
date = None
if rec.stage == "done":
dates = rec.ra_bill_ids.mapped('date')
if dates:
date = dates[-1]
rec.completion_date = date
class EquipContractLine(models.Model):
_name = 'equip.contract.line'
_description = "Equip Contract Line"
_rec_name = 'remark'
_inherit = ['mail.thread', 'mail.activity.mixin']
contract_id = fields.Many2one('equipment.subcontract', string="Subcontract", ondelete='cascade')
percentage = fields.Float(string="Percentage", tracking=True, compute="_compute_percentage")
company_id = fields.Many2one('res.company', string='Company', default=lambda self: self.env.company)
currency_id = fields.Many2one('res.currency', related='company_id.currency_id', string='Currency')
amount = fields.Monetary(tracking=True, string="Amount", compute="_compute_percentage_amount")
date = fields.Date(string="Date", default=fields.Date.today(), tracking=True)
remark = fields.Char(string="Remark", tracking=True)
purchase_order_id = fields.Many2one('purchase.order', string="Purchase Order")
bill_id = fields.Many2one('account.move', string="Bill")
payment_state = fields.Selection(related="bill_id.payment_state", string="Payment State", tracking=True)
state = fields.Selection(related="purchase_order_id.state", string="State", tracking=True)
po_bill = fields.Selection(related="contract_id.po_bill")
qty = fields.Integer(string="Qty")
retention_percentage = fields.Float(string="Retention(%)")
retention_amount = fields.Monetary(string="Retention Amount", compute="compute_retention_amount")
final_amount = fields.Monetary(string="Total Amount", compute="_compute_final_amount")
# QC Check
qc_user_id = fields.Many2one('res.users', string="QC Responsible", tracking=True)
qc_status = fields.Selection(
[('draft', 'Draft'),
('request', 'Department Approval'),
('approve', 'Approve'),
('reject', 'Reject')], default='draft', string="Quality Check Status", tracking=True)
reject_reason = fields.Text(string="Reject Reason", tracking=True)
def unlink(self):
for rec in self:
if rec.qc_status != 'draft':
raise ValidationError(_("You can't delete until Quality Check status is in Draft"))
else:
return super(EquipContractLine, self).unlink()
@api.constrains('qty')
def _check_ra_bill_qty(self):
ra_bill_ids = self.env['equip.contract.line'].search([('contract_id', '=', self.contract_id.id)])
qty = 0
for record in ra_bill_ids:
if record.qc_status != 'reject':
qty = qty + record.qty
if qty > self.contract_id.qty:
raise ValidationError(_("Quantity should be less than total qty."))
@api.depends('contract_id', 'qty', 'contract_id.tax_id')
def _compute_percentage_amount(self):
for rec in self:
amount = 0.0
if rec.qty and rec.contract_id:
amount = (rec.contract_id.cost + (rec.contract_id.tax_id.amount * rec.contract_id.cost / 100)) * rec.qty
rec.amount = amount
@api.depends('qty', 'retention_amount')
def _compute_final_amount(self):
for rec in self:
total = 0.0
if rec.amount:
total = rec.amount - rec.retention_amount
rec.final_amount = total
@api.depends('amount', 'retention_percentage')
def compute_retention_amount(self):
for rec in self:
retention_amount = 0.0
if rec.retention_percentage:
retention_amount = rec.amount * rec.retention_percentage / 100
rec.retention_amount = retention_amount
@api.depends('contract_id', 'amount')
def _compute_percentage(self):
for rec in self:
percentage = 0.0
if rec.contract_id and rec.amount > 0:
percentage = (100 * rec.amount) / rec.contract_id.total_cost
rec.percentage = percentage
def action_quality_check(self):
self.qc_status = 'request'
def action_quality_check_approve(self):
self.qc_status = 'approve'
self.qc_user_id = self.env.user.id
def action_quality_check_reject(self):
self.qc_status = 'reject'
self.qc_user_id = self.env.user.id
def action_reset_to_draft(self):
self.qc_status = 'draft'
def action_create_ra_bill(self):
if self.po_bill == 'bill':
record = {
'product_id': self.contract_id.equipment_id.id,
'name': self.contract_id.name,
'quantity': 1,
'price_unit': self.final_amount,
'tax_ids': False
}
invoice_lines = [(0, 0, record)]
data = {
'partner_id': self.contract_id.vendor_id.id,
'invoice_date': self.date,
'invoice_line_ids': invoice_lines,
'move_type': 'in_invoice',
'equipment_subcontract_id': self.contract_id.id,
'job_order_id': self.contract_id.job_order_id.id,
'purchase_order': 'equipment'
}
invoice_id = self.env['account.move'].sudo().create(data)
self.bill_id = invoice_id.id
remaining_amount = self.contract_id.remaining_amount
self.contract_id.remaining_amount = remaining_amount - self.amount
qty = self.contract_id.remain_qty
self.contract_id.remain_qty = qty - self.qty
elif self.po_bill == 'purchase_order':
purchase_record = {
'product_id': self.contract_id.equipment_id.id,
'name': self.contract_id.name,
'product_qty': 1,
'price_unit': self.final_amount,
}
purchase_lines = [(0, 0, purchase_record)]
purchase_data = {
'partner_id': self.contract_id.vendor_id.id,
'order_line': purchase_lines,
'job_order_id': self.contract_id.job_order_id.id,
'equipment_subcontract_id': self.contract_id.id,
'purchase_order': 'equipment'
}
purchase_order_id = self.env['purchase.order'].create(purchase_data)
self.purchase_order_id = purchase_order_id.id
remaining_amount = self.contract_id.remaining_amount
self.contract_id.remaining_amount = remaining_amount - self.amount
qty = self.contract_id.remain_qty
self.contract_id.remain_qty = qty - self.qty
class LabourSubcontract(models.Model):
_name = 'labour.subcontract'
_description = "Labour Sub Contract"
_rec_name = 'seq'
seq = fields.Char(string='Sequence', required=True, readonly=True, default=lambda self: _('New'))
name = fields.Char(string="Title")
product_id = fields.Many2one('product.product', string="Product", domain="[('is_labour','=',True)]")
company_id = fields.Many2one('res.company', string='Company', default=lambda self: self.env.company)
currency_id = fields.Many2one('res.currency', related='company_id.currency_id', string='Currency')
cost = fields.Monetary(string="Cost / Hour")
po_bill = fields.Selection([('bill', 'Bill'), ('purchase_order', 'Purchase Order')], string="Type",
default='bill')
stage = fields.Selection([('draft', 'Draft'), ('in_progress', 'In Progress'), ('done', 'Done')],
default='draft')
vendor_id = fields.Many2one('res.partner', string="Contractor")
job_type_id = fields.Many2one('job.type', string="Work Type")
sub_category_id = fields.Many2one('job.sub.category', string="Work Sub Type")
ra_bill_ids = fields.One2many('labour.contract.line', 'contract_id', string="Ra Bills")
# Project Details
job_order_id = fields.Many2one('job.order', string="Work Order")
phase_id = fields.Many2one(related="job_order_id.job_sheet_id", string="Project Phase(WBS)", store=True)
project_id = fields.Many2one(related='job_order_id.project_id', string="Sub Project", store=True)
task_id = fields.Many2one(related="job_order_id.task_id", string="Task", store=True)
# Department
department_id = fields.Many2one(related="job_order_id.department_id", string="Department", store=True)
manager_ids = fields.Many2many('res.users', store=True, string="Manager")
user_id = fields.Many2one(related="job_order_id.user_id", string="Responsible")
# Calculation
hours = fields.Float(string="Hours")
remain_hours = fields.Float(string="Remaining Hours")
total_cost = fields.Monetary(string="Total Cost")
remaining_amount = fields.Monetary(string="Remaining Amount")
progress = fields.Float(string="Completed Billing", compute="_compute_payment_progress")
tax_id = fields.Many2one('account.tax', string='Tax')
completion_date = fields.Date(string="Completion Date", compute="compute_completion_date")
@api.model_create_multi
def create(self, vals_list):
for vals in vals_list:
if vals.get('seq', _('New')) == _('New'):
vals['seq'] = self.env['ir.sequence'].next_by_code('labour.sub') or _('New')
res = super(LabourSubcontract, self).create(vals_list)
return res
def action_in_progress(self):
self.stage = 'in_progress'
def action_state_done(self):
self.stage = 'done'
@api.constrains('ra_bill_ids', 'hours')
def _check_ra_bill_hours(self):
hours = 0
for record in self.ra_bill_ids:
if record.qc_status != 'reject':
hours = hours + record.hours
if hours > self.hours:
raise ValidationError(_("Hours should be less than total hours"))
@api.depends('total_cost', 'remaining_amount')
def _compute_payment_progress(self):
for rec in self:
progress = 0.0
if rec.total_cost and rec.remaining_amount:
progress = (rec.remaining_amount * 100) / rec.total_cost
rec.progress = 100 - progress
@api.depends('stage', 'ra_bill_ids')
def compute_completion_date(self):
for rec in self:
date = None
if rec.stage == "done":
dates = rec.ra_bill_ids.mapped('date')
if dates:
date = dates[-1]
rec.completion_date = date
class LabourContractLine(models.Model):
_name = 'labour.contract.line'
_description = "Labour Contract Line"
_rec_name = 'remark'
_inherit = ['mail.thread', 'mail.activity.mixin']
contract_id = fields.Many2one('labour.subcontract', string="Labour Subcontract", ondelete='cascade')
percentage = fields.Float(string="Percentage", tracking=True, compute="_compute_percentage")
company_id = fields.Many2one('res.company', string='Company', default=lambda self: self.env.company)
currency_id = fields.Many2one('res.currency', related='company_id.currency_id', string='Currency')
amount = fields.Monetary(tracking=True, string="Amount", compute="_compute_percentage_amount")
date = fields.Date(string="Date", default=fields.Date.today(), tracking=True)
remark = fields.Char(string="Remark", tracking=True)
purchase_order_id = fields.Many2one('purchase.order', string="Purchase Order")
bill_id = fields.Many2one('account.move', string="Bill")
payment_state = fields.Selection(related="bill_id.payment_state", string="Payment State", tracking=True)
state = fields.Selection(related="purchase_order_id.state", string="State", tracking=True)
po_bill = fields.Selection(related="contract_id.po_bill")
hours = fields.Float(string="Hours")
retention_percentage = fields.Float(string="Retention(%)")
retention_amount = fields.Monetary(string="Retention Amount", compute="compute_retention_amount")
final_amount = fields.Monetary(string="Total Amount", compute="_compute_final_amount")
# QC Check
qc_user_id = fields.Many2one('res.users', string="QC Responsible", tracking=True)
qc_status = fields.Selection([('draft', 'Draft'),
('request', 'Department Approval'),
('approve', 'Approve'),
('reject', 'Reject')],
default='draft', string="Quality Check Status", tracking=True)
reject_reason = fields.Text(string="Reject Reason", tracking=True)
def unlink(self):
for rec in self:
if rec.qc_status != 'draft':
raise ValidationError(_("You can't delete until Quality Check status is in Draft"))
else:
return super(LabourContractLine, self).unlink()
@api.constrains('hours')
def _check_ra_bill_hours(self):
ra_bill_ids = self.env['labour.contract.line'].search([('contract_id', '=', self.contract_id.id)])
hours = 0
for record in ra_bill_ids:
if record.qc_status != 'reject':
hours = hours + record.hours
if hours > self.contract_id.hours:
raise ValidationError(_("Hours should be less than total hours"))
@api.depends('contract_id', 'hours', 'contract_id.tax_id')
def _compute_percentage_amount(self):
for rec in self:
amount = 0.0
if rec.hours and rec.contract_id:
amount = (rec.contract_id.cost + (
rec.contract_id.tax_id.amount * rec.contract_id.cost / 100)) * rec.hours
rec.amount = amount
@api.depends('hours', 'retention_amount')
def _compute_final_amount(self):
for rec in self:
total = 0.0
if rec.amount:
total = rec.amount - rec.retention_amount
rec.final_amount = total
@api.depends('amount', 'retention_percentage')
def compute_retention_amount(self):
for rec in self:
retention_amount = 0.0
retention_amount = rec.amount * rec.retention_percentage / 100
rec.retention_amount = retention_amount
@api.depends('contract_id', 'amount')
def _compute_percentage(self):
for rec in self:
percentage = 0.0
if rec.contract_id and rec.amount > 0:
percentage = (100 * rec.amount) / rec.contract_id.total_cost
rec.percentage = percentage
def action_quality_check(self):
self.qc_status = 'request'
def action_quality_check_approve(self):
self.qc_status = 'approve'
self.qc_user_id = self.env.user.id
def action_quality_check_reject(self):
self.qc_status = 'reject'
self.qc_user_id = self.env.user.id
def action_reset_to_draft(self):
self.qc_status = 'draft'
def action_create_ra_bill(self):
if self.po_bill == 'bill':
record = {
'product_id': self.contract_id.product_id.id,
'name': self.contract_id.name,
'quantity': 1,
'price_unit': self.final_amount,
'tax_ids': False
}
invoice_lines = [(0, 0, record)]
data = {
'partner_id': self.contract_id.vendor_id.id,
'invoice_date': self.date,
'invoice_line_ids': invoice_lines,
'move_type': 'in_invoice',
'labour_subcontract_id': self.contract_id.id,
'job_order_id': self.contract_id.job_order_id.id,
'purchase_order': 'equipment'
}
invoice_id = self.env['account.move'].sudo().create(data)
remaining_amount = self.contract_id.remaining_amount
self.contract_id.remaining_amount = remaining_amount - self.amount
self.bill_id = invoice_id.id
qty = self.contract_id.remain_hours
self.contract_id.remain_hours = qty - self.hours
elif self.po_bill == 'purchase_order':
purchase_record = {
'product_id': self.contract_id.product_id.id,
'name': self.contract_id.name
,
'product_qty': 1,
'price_unit': self.final_amount,
}
purchase_lines = [(0, 0, purchase_record)]
purchase_data = {
'partner_id': self.contract_id.vendor_id.id,
'order_line': purchase_lines,
'job_order_id': self.contract_id.job_order_id.id,
'labour_subcontract_id': self.contract_id.id,
'purchase_order': 'equipment'
}
purchase_order_id = self.env['purchase.order'].create(purchase_data)
self.purchase_order_id = purchase_order_id.id
remaining_amount = self.contract_id.remaining_amount
self.contract_id.remaining_amount = remaining_amount - self.amount
qty = self.contract_id.remain_hours
self.contract_id.remain_hours = qty - self.hours
class OverheadSubcontract(models.Model):
_name = 'overhead.subcontract'
_description = "Overhead Subcontract"
_rec_name = 'seq'
seq = fields.Char(string='Sequence', required=True, readonly=True, default=lambda self: _('New'))
name = fields.Char(string="Title")
product_id = fields.Many2one('product.product', string="Product", domain="[('is_overhead','=',True)]")
company_id = fields.Many2one('res.company', string='Company', default=lambda self: self.env.company)
currency_id = fields.Many2one('res.currency', related='company_id.currency_id', string='Currency')
uom_id = fields.Many2one(related="product_id.uom_po_id", string="Unit of Measure")
cost = fields.Monetary(string="Cost / Unit")
po_bill = fields.Selection([('bill', 'Bill'), ('purchase_order', 'Purchase Order')], string="Type", default='bill')
stage = fields.Selection([('draft', 'Draft'), ('in_progress', 'In Progress'), ('done', 'Done')], default='draft')
vendor_id = fields.Many2one('res.partner', string="Vendor")
job_type_id = fields.Many2one('job.type', string="Work Type")
sub_category_id = fields.Many2one('job.sub.category', string="Work Sub Type")
ra_bill_ids = fields.One2many('overhead.contract.line', 'contract_id', string="Ra Bills")
# Project Details
job_order_id = fields.Many2one('job.order', string="Work Order")
phase_id = fields.Many2one(related="job_order_id.job_sheet_id", string="Project Phase(WBS)", store=True)
project_id = fields.Many2one(related='job_order_id.project_id', string="Sub Project", store=True)
task_id = fields.Many2one(related="job_order_id.task_id", string="Task", store=True)
# Department
department_id = fields.Many2one(related="job_order_id.department_id", string="Department", store=True)
manager_ids = fields.Many2many('res.users', store=True, string="Manager")
user_id = fields.Many2one(related="job_order_id.user_id", string="Responsible")
# Calculation
qty = fields.Integer(string="Qty.", default=1)
remain_qty = fields.Integer(string="Remaining Qty")
total_cost = fields.Monetary(string="Total Cost")
remaining_amount = fields.Monetary(string="Remaining Amount")
progress = fields.Float(string="Completed Billing", compute="_compute_payment_progress")
tax_id = fields.Many2one('account.tax', string='Tax')
completion_date = fields.Date(string="Completion Date", compute="compute_completion_date")
@api.model_create_multi
def create(self, vals_list):
for vals in vals_list:
if vals.get('seq', _('New')) == _('New'):
vals['seq'] = self.env['ir.sequence'].next_by_code('overhead.sub') or _('New')
res = super(OverheadSubcontract, self).create(vals_list)
return res
def action_in_progress(self):
self.stage = 'in_progress'
def action_state_done(self):
self.stage = 'done'
@api.constrains('ra_bill_ids', 'qty')
def _check_ra_bill_qty(self):
qty = 0
for record in self.ra_bill_ids:
if record.qc_status != 'reject':
qty = qty + record.qty
if qty > self.qty:
raise ValidationError(_("Quantity should be less than total qty."))
@api.depends('total_cost', 'remaining_amount')
def _compute_payment_progress(self):
for rec in self:
progress = 0.0
if rec.total_cost and rec.remaining_amount:
progress = (rec.remaining_amount * 100) / rec.total_cost
rec.progress = 100 - progress
@api.depends('stage', 'ra_bill_ids')
def compute_completion_date(self):
for rec in self:
date = None
if rec.stage == "done":
dates = rec.ra_bill_ids.mapped('date')
if dates:
date = dates[-1]
rec.completion_date = date
class OverheadContractLine(models.Model):
_name = 'overhead.contract.line'
_description = "Overhead Contract Line"
_rec_name = 'remark'
_inherit = ['mail.thread', 'mail.activity.mixin']
contract_id = fields.Many2one('overhead.subcontract', string="Overhead Subcontract", ondelete='cascade')
percentage = fields.Float(string="Percentage", tracking=True, compute="_compute_percentage")
company_id = fields.Many2one('res.company', string='Company', default=lambda self: self.env.company)
currency_id = fields.Many2one('res.currency', related='company_id.currency_id', string='Currency')
amount = fields.Monetary(tracking=True, string="Amount", compute="_compute_percentage_amount")
date = fields.Date(string="Date", default=fields.Date.today(), tracking=True)
remark = fields.Char(string="Remark", tracking=True)
purchase_order_id = fields.Many2one('purchase.order', string="Purchase Order")
bill_id = fields.Many2one('account.move', string="Bill")
payment_state = fields.Selection(related="bill_id.payment_state", string="Payment State", tracking=True)
state = fields.Selection(related="purchase_order_id.state", string="State", tracking=True)
po_bill = fields.Selection(related="contract_id.po_bill")
qty = fields.Integer(string="Qty")
retention_percentage = fields.Float(string="Retention(%)")
retention_amount = fields.Monetary(string="Retention Amount", compute="compute_retention_amount")
final_amount = fields.Monetary(string="Total Amount", compute="_compute_final_amount")
# QC Check
qc_user_id = fields.Many2one('res.users', string="QC Responsible", tracking=True)
qc_status = fields.Selection([('draft', 'Draft'),
('request', 'Department Approval'),
('approve', 'Approve'),
('reject', 'Reject')], default='draft', string="Quality Check Status", tracking=True)
reject_reason = fields.Text(string="Reject Reason", tracking=True)
def unlink(self):
for rec in self:
if rec.qc_status != 'draft':
raise ValidationError(_("You can't delete until Quality Check status is in Draft"))
else:
return super(OverheadContractLine, self).unlink()
@api.constrains('qty')
def _check_ra_bill_qty(self):
ra_bill_ids = self.env['overhead.contract.line'].search([('contract_id', '=', self.contract_id.id)])
qty = 0
for record in ra_bill_ids:
if record.qc_status != 'reject':
qty = qty + record.qty
if qty > self.contract_id.qty:
raise ValidationError(_("Quantity should be less than total qty."))
@api.depends('contract_id', 'qty', 'contract_id.tax_id')
def _compute_percentage_amount(self):
for rec in self:
amount = 0.0
if rec.qty and rec.contract_id:
amount = (rec.contract_id.cost + (rec.contract_id.tax_id.amount * rec.contract_id.cost / 100)) * rec.qty
rec.amount = amount
@api.depends('qty', 'retention_amount')
def _compute_final_amount(self):
for rec in self:
total = 0.0
if rec.amount:
total = rec.amount - rec.retention_amount
rec.final_amount = total
@api.depends('amount', 'retention_percentage')
def compute_retention_amount(self):
for rec in self:
retention_amount = 0.0
if rec.retention_percentage:
retention_amount = rec.amount * rec.retention_percentage / 100
rec.retention_amount = retention_amount
@api.depends('contract_id', 'amount')
def _compute_percentage(self):
for rec in self:
percentage = 0.0
if rec.contract_id and rec.amount > 0:
percentage = (100 * rec.amount) / rec.contract_id.total_cost
rec.percentage = percentage
def action_quality_check(self):
self.qc_status = 'request'
def action_quality_check_approve(self):
self.qc_status = 'approve'
self.qc_user_id = self.env.user.id
def action_quality_check_reject(self):
self.qc_status = 'reject'
self.qc_user_id = self.env.user.id
def action_reset_to_draft(self):
self.qc_status = 'draft'
def action_create_ra_bill(self):
if self.po_bill == 'bill':
record = {
'product_id': self.contract_id.product_id.id,
'name': self.contract_id.name,
'quantity': 1,
'price_unit': self.final_amount,
'tax_ids': False
}
invoice_lines = [(0, 0, record)]
data = {
'partner_id': self.contract_id.vendor_id.id,
'invoice_date': self.date,
'invoice_line_ids': invoice_lines,
'move_type': 'in_invoice',
'overhead_subcontract_id': self.contract_id.id,
'job_order_id': self.contract_id.job_order_id.id,
'purchase_order': 'overhead'
}
invoice_id = self.env['account.move'].sudo().create(data)
remaining_amount = self.contract_id.remaining_amount
self.contract_id.remaining_amount = remaining_amount - self.amount
self.bill_id = invoice_id.id
qty = self.contract_id.remain_qty
self.contract_id.remain_qty = qty - self.qty
elif self.po_bill == 'purchase_order':
purchase_record = {
'product_id': self.contract_id.product_id.id,
'name': self.contract_id.name
,
'product_qty': 1,
'price_unit': self.final_amount,
}
purchase_lines = [(0, 0, purchase_record)]
purchase_data = {
'partner_id': self.contract_id.vendor_id.id,
'order_line': purchase_lines,
'job_order_id': self.contract_id.job_order_id.id,
'overhead_subcontract_id': self.contract_id.id,
'purchase_order': 'overhead'
}
purchase_order_id = self.env['purchase.order'].create(
purchase_data)
self.purchase_order_id = purchase_order_id.id
remaining_amount = self.contract_id.remaining_amount
self.contract_id.remaining_amount = remaining_amount - self.amount
qty = self.contract_id.remain_qty
self.contract_id.remain_qty = qty - self.qty
class MaterialConsume(models.Model):
_name = 'material.consume'
_description = "Material Consume Order"
_inherit = ['mail.thread', 'mail.activity.mixin']
_rec_name = 'seq'
seq = fields.Char(string='Sequence', required=True, readonly=True, default=lambda self: _('New'))
date = fields.Date(string="Date", default=fields.Date.today())
remark = fields.Char(string="Remark")
warehouse_id = fields.Many2one('stock.warehouse')
consume_order_id = fields.Many2one('stock.picking', string="Consume Order")
state = fields.Selection(related="consume_order_id.state", string="Status")
consume_order_ids = fields.One2many('material.consume.line', 'material_consume_id', string="Material Consume")
# Project Details
job_order_id = fields.Many2one('job.order', string="Work Order")
phase_id = fields.Many2one(related="job_order_id.job_sheet_id", string="Project Phase(WBS)", store=True)
project_id = fields.Many2one(related='job_order_id.project_id', string="Sub Project", store=True)
task_id = fields.Many2one(related="job_order_id.task_id", string="Task", store=True)
# Department
department_id = fields.Many2one(related="job_order_id.department_id", string="Department", store=True)
manager_ids = fields.Many2many('res.users', store=True, string="Manager")
user_id = fields.Many2one(related="job_order_id.user_id", string="Responsible", store=True)
# Quality Check
qc_user_id = fields.Many2one('res.users', string="QC Responsible", tracking=True)
qc_status = fields.Selection([('draft', 'Draft'), ('request', 'Department Approval'), ('approve', 'Approve'),
('reject', 'Reject'), ('cancel', 'Cancel')], default='draft',
string="Quality Check Status", tracking=True)
reject_reason = fields.Text(string="Reject Reason", tracking=True)
@api.model_create_multi
def create(self, vals_list):
for vals in vals_list:
if vals.get('seq', _('New')) == _('New'):
vals['seq'] = self.env['ir.sequence'].next_by_code('material.consume') or _('New')
res = super(MaterialConsume, self).create(vals_list)
return res
def unlink(self):
if self.qc_status != 'draft':
raise ValidationError(_("You can't delete until Quality Check status is in Draft"))
else:
return super(MaterialConsume, self).unlink()
@api.constrains('consume_order_ids')
def _check_material_line_qty(self):
for rec in self.consume_order_ids:
if rec.qty > rec.material_line_id.remain_qty:
raise ValidationError(_("Qty should be less than remain Qty."))
def action_quality_check(self):
self.qc_status = 'request'
def action_quality_check_approve(self):
self.qc_status = 'approve'
self.qc_user_id = self.env.user.id
def action_quality_check_reject(self):
self.qc_status = 'reject'
self.qc_user_id = self.env.user.id
def action_reset_to_draft(self):
self.qc_status = 'draft'
def action_cancel_consume_order(self):
self.qc_status = 'cancel'
def action_create_consume_order(self):
dest_location_id = False
if self.warehouse_id.consume_stock_location_id:
dest_location_id = self.warehouse_id.consume_stock_location_id
else:
dest_location_id = self.env['stock.location'].create(
{'name': "Consume Location/" + str(self.warehouse_id.name), 'usage': 'production'})
self.warehouse_id.consume_stock_location_id = dest_location_id.id
lines = []
for rec in self.consume_order_ids:
lines.append((0, 0, {
'product_id': rec.material_id.id,
'product_uom_qty': rec.qty,
'product_uom': rec.uom_id.id,
'location_id': self.warehouse_id.lot_stock_id.id,
'location_dest_id': dest_location_id.id,
'name': rec.name
}))
source_id = self.warehouse_id.lot_stock_id
stock_picking_type_id = self.env['stock.picking.type'].search(
[('code', '=', 'outgoing'), ('warehouse_id', '=', self.warehouse_id.id)], limit=1)
delivery_record = {
'picking_type_id': stock_picking_type_id.id,
'location_id': source_id.id,
'location_dest_id': dest_location_id.id,
'move_ids_without_package': lines,
'consume_order_id': self.job_order_id.id,
'material_consume_id': self.id,
'move_type': 'one'
}
delivery_id = self.env['stock.picking'].create(delivery_record)
self.consume_order_id = delivery_id.id
for rec in self.consume_order_ids:
remain_qty = rec.material_line_id.remain_qty
usage_qty = rec.material_line_id.usage_qty
rec.material_line_id.remain_qty = remain_qty - rec.qty
rec.material_line_id.usage_qty = usage_qty + rec.qty
return {
'type': 'ir.actions.act_window',
'name': _('Consume Order'),
'res_model': 'stock.picking',
'res_id': delivery_id.id,
'view_mode': 'form',
'target': 'current'
}
class MaterialConsumeLine(models.Model):
_name = 'material.consume.line'
_description = "Material Consume Line"
material_id = fields.Many2one('product.product', string="Material", domain="[('is_material','=',True)]")
uom_id = fields.Many2one(related="material_id.uom_id", string="UOM")
name = fields.Char(string="Description")
qty = fields.Integer(string="Qty")
material_consume_id = fields.Many2one('material.consume', string="Material Consume")
qc_status = fields.Selection(related="material_consume_id.qc_status")
material_line_id = fields.Many2one('order.material.line')