You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
233 lines
10 KiB
233 lines
10 KiB
# -*- coding: utf-8 -*-
|
|
##############################################################################
|
|
#
|
|
# Cybrosys Technologies Pvt. Ltd.
|
|
#
|
|
# Copyright (C) 2024-TODAY Cybrosys Technologies(<https://www.cybrosys.com>)
|
|
# Author: Aysha Shalin (odoo@cybrosys.com)
|
|
#
|
|
# You can modify it under the terms of the GNU AFFERO
|
|
# GENERAL PUBLIC LICENSE (AGPL v3), Version 3.
|
|
#
|
|
# This program is distributed in the hope that it will be useful,
|
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
# GNU AFFERO GENERAL PUBLIC LICENSE (AGPL v3) for more details.
|
|
#
|
|
# You should have received a copy of the GNU AFFERO GENERAL PUBLIC LICENSE
|
|
# (AGPL v3) along with this program.
|
|
# If not, see <http://www.gnu.org/licenses/>.
|
|
#
|
|
##############################################################################
|
|
from datetime import datetime
|
|
from odoo import api, fields, models
|
|
from odoo.exceptions import ValidationError
|
|
|
|
|
|
class LabourSupply(models.Model):
|
|
""" Class to create contract for labour supply """
|
|
_name = "labour.supply"
|
|
_description = "Contract creation"
|
|
_inherit = ['mail.thread', 'mail.activity.mixin']
|
|
_rec_name = 'sequence_number'
|
|
|
|
sequence_number = fields.Char(string="Sequence Number", readonly=True,
|
|
copy=False, default="New",
|
|
help="Field to specify sequence number")
|
|
customer_id = fields.Many2one('res.partner', string="Customer",
|
|
help="Field to choose customer",
|
|
required=True)
|
|
skill_ids = fields.One2many('labour.on.skill',
|
|
'labour_supply_id',
|
|
string="Skills Required", required=True,
|
|
help="Field to choose skill and number "
|
|
"required")
|
|
company_id = fields.Many2one('res.company', string='Company',
|
|
required=True,
|
|
default=lambda self: self.env.company)
|
|
from_date = fields.Date(string="From Date", tracking=True,
|
|
help="Field to choose from date")
|
|
to_date = fields.Date(string="To Date", tracking=True,
|
|
help="Field to choose to date")
|
|
state = fields.Selection([('draft', 'Draft'), ('ready', 'Ready'),
|
|
('confirmed', 'Confirmed'),
|
|
('invoiced', 'Invoiced'),
|
|
('canceled', 'Canceled'),
|
|
('expired', 'Expired')],
|
|
string="State", default="draft", tracking=True,
|
|
help="Field to specify state")
|
|
workers_ids = fields.Many2many('workers.details',
|
|
string="Select Workers",
|
|
readonly=True,
|
|
help="Field to choose workers")
|
|
total_amount = fields.Monetary(tracking=True, readonly=True,
|
|
string="Total Amount", help="Total amount")
|
|
currency_id = fields.Many2one('res.currency',
|
|
string='Currency', help="Currency",
|
|
related='company_id.currency_id')
|
|
period = fields.Integer(string="Period", help="The period of contract")
|
|
invoice_id = fields.Many2one('account.move', string="Invoice",
|
|
help="The invoice of contract")
|
|
is_alert = fields.Boolean(string="Alert",
|
|
help="Boolean field to control the visibility "
|
|
"of alert visibility")
|
|
view_workers_page = fields.Boolean(default=False, string="View Worker Page",
|
|
help="Field to control the"
|
|
" visibility of workers page ")
|
|
|
|
@api.model
|
|
def create(self, vals):
|
|
"""
|
|
Summary:
|
|
function return sequence number for record
|
|
Args:
|
|
vals:To store the sequence created
|
|
return:
|
|
result:return sequence created
|
|
"""
|
|
vals['sequence_number'] = self.env['ir.sequence'].next_by_code(
|
|
'labour.supply') or 'New'
|
|
return super(LabourSupply, self).create(vals)
|
|
|
|
def cron_change_state(self):
|
|
"""
|
|
Summary: function changes the state of worker when the worker have
|
|
ongoing work and also change the state when the contact expire.
|
|
"""
|
|
labour_supplies = self.env['labour.supply'].search(
|
|
[('state', 'not in', ['draft', 'cancel'])])
|
|
for labour_supply in labour_supplies:
|
|
if labour_supply.to_date < fields.Date.today():
|
|
labour_supply.write({'state': 'expired'})
|
|
for worker in labour_supply.workers_ids:
|
|
worker.write({'state': 'available'})
|
|
labours_supplies = self.env['labour.supply'].search(
|
|
[('state', '=', 'invoiced')])
|
|
for contract in labours_supplies:
|
|
if contract.from_date == fields.Date.today():
|
|
for labour in contract.workers_ids:
|
|
labour.write({'state': 'not_available'})
|
|
|
|
def action_confirm(self):
|
|
"""
|
|
Summary: function confirm the record state
|
|
"""
|
|
self.write({'state': 'confirmed'})
|
|
|
|
def action_draft(self):
|
|
"""
|
|
Summary: function change the record state to draft
|
|
"""
|
|
self.total_amount = 0
|
|
self.workers_ids = False
|
|
self.view_workers_page = False
|
|
self.is_alert = False
|
|
self.state = 'draft'
|
|
|
|
def action_cancel(self):
|
|
"""
|
|
summary: function change the record state to cancelled
|
|
"""
|
|
for worker in self.workers_ids:
|
|
worker.write({'state': 'available'})
|
|
self.write({'state': 'canceled'})
|
|
|
|
def action_create_invoice(self):
|
|
"""
|
|
summary: function change the record state to invoice, create invoice on
|
|
the basis of total amount and return invoice
|
|
"""
|
|
if self.from_date == fields.Date.today():
|
|
for worker in self.workers_ids:
|
|
worker.write({'state': 'not_available'})
|
|
invoice = self.env['account.move'].create({
|
|
'move_type': 'out_invoice',
|
|
'partner_id': self.customer_id.id,
|
|
'currency_id': self.currency_id.id,
|
|
'invoice_date': self.to_date,
|
|
'invoice_origin': self.sequence_number,
|
|
'invoice_line_ids': [(0, 0, {
|
|
'name': "contract cost",
|
|
'quantity': 1,
|
|
'price_unit': self.total_amount,
|
|
})],
|
|
})
|
|
self.invoice_id = invoice.id
|
|
self.write({'state': 'invoiced'})
|
|
return {
|
|
'name': 'create_invoice',
|
|
'type': 'ir.actions.act_window',
|
|
'view_mode': 'form',
|
|
'res_id': invoice.id,
|
|
'res_model': 'account.move',
|
|
'target': 'current'
|
|
}
|
|
|
|
def action_labour_supply_invoices(self):
|
|
"""
|
|
Summary: function returns invoice for current record
|
|
return: returns invoices created
|
|
"""
|
|
return {
|
|
'name': 'Create Invoice',
|
|
'type': 'ir.actions.act_window',
|
|
'view_mode': 'tree,form',
|
|
'res_model': 'account.move',
|
|
'domain': [('invoice_origin', '=', self.sequence_number)]
|
|
}
|
|
|
|
def action_fetch(self):
|
|
"""
|
|
Summary: function change the record state to Ready, calculate total
|
|
amount according workers assigned also calculate the total from date and
|
|
to date.
|
|
"""
|
|
self.workers_ids = False
|
|
self.total_amount = 0
|
|
if self.skill_ids:
|
|
date_list = []
|
|
for skill in self.skill_ids:
|
|
if skill.from_date < fields.Date.today() or \
|
|
skill.to_date < fields.Date.today():
|
|
raise ValidationError("Enter valid date ")
|
|
if skill.to_date < skill.from_date:
|
|
raise ValidationError("Invalid start date and end date ")
|
|
labour_not_available = self.env['labour.supply'].search(
|
|
[('state', '=', "invoiced"),
|
|
('from_date', '<', fields.Date.today())
|
|
, ('to_date', '>', fields.Date.today())]).mapped(
|
|
'workers_ids.id')
|
|
labours_selected = []
|
|
for skill in self.skill_ids:
|
|
count = 0
|
|
date_list.append(skill.from_date)
|
|
date_list.append(skill.to_date)
|
|
worker_details = self.env['workers.details'].search([])
|
|
labour_available = worker_details.search(
|
|
[('skill_ids', '=', skill.skill_id.id),
|
|
('state', '=', 'available'),
|
|
('id', 'not in', labours_selected),
|
|
('id', 'not in', labour_not_available)]).mapped('id')
|
|
labours_selected = labours_selected + labour_available
|
|
if len(labour_available) < skill.number_of_labour_required:
|
|
self.is_alert = True
|
|
for worker in worker_details:
|
|
if worker.id in labour_available:
|
|
if count < skill.number_of_labour_required:
|
|
count = count + 1
|
|
self.write({'workers_ids': [(4, worker.id,)]})
|
|
date_start = datetime.strptime(str(skill.from_date),
|
|
'%Y-%m-%d')
|
|
date_end = datetime.strptime(str(skill.to_date),
|
|
'%Y-%m-%d')
|
|
period = date_end - date_start
|
|
self.period = int(str(period.days))
|
|
self.total_amount = self.total_amount + (
|
|
worker.rate * (self.period + 1))
|
|
date_list = sorted(date_list)
|
|
self.from_date = date_list[0]
|
|
self.to_date = date_list[-1]
|
|
self.view_workers_page = True
|
|
self.state = 'ready'
|
|
else:
|
|
raise ValidationError("Enter Skill Required")
|
|
|