diff --git a/job_card_management/README.rst b/job_card_management/README.rst new file mode 100644 index 000000000..c7b306466 --- /dev/null +++ b/job_card_management/README.rst @@ -0,0 +1,45 @@ +.. image:: https://img.shields.io/badge/licence-AGPL--3-blue.svg + :target: http://www.gnu.org/licenses/agpl-3.0-standalone.html + :alt: License: AGPL-3 + +Job Card Management v16 +======================= +Job Card Management + +Installation +============ + - www.odoo.com/documentation/16.0/setup/install.html + - Install our custom addon + +Configuration +============= + +No additional configurations needed + +Credits +======= +Developer: Manasa T P v16 @ cybrosys, Contact: odoo@cybrosys.com + +Contacts +-------- +* Mail Contact : odoo@cybrosys.com +* Website : https://cybrosys.com + +Bug Tracker +----------- +Bugs are tracked on GitHub Issues. In case of trouble, please check there if +your issue has already been reported. + +Maintainer +========== +.. image:: https://cybrosys.com/images/logo.png + :target: https://cybrosys.com + +This module is maintained by Cybrosys Technologies. + +For support and more information, please visit `Our Website `__ + +Further information +=================== +HTML Description: ``__ + diff --git a/job_card_management/__init__.py b/job_card_management/__init__.py new file mode 100644 index 000000000..15533ea98 --- /dev/null +++ b/job_card_management/__init__.py @@ -0,0 +1,24 @@ +# -*- coding: utf-8 -*- +################################################################################### +# Job Card Management +# +# Cybrosys Technologies Pvt. Ltd. +# Copyright (C) 2025-TODAY Cybrosys Technologies (). +# Author: Manasa T P () +# +# This program is free software: you can modify +# it under the terms of the GNU Affero General Public License (AGPL) as +# published by the Free Software Foundation, either version 3 of the +# License, or (at your option) any later version. +# +# 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 for more details. +# +# You should have received a copy of the GNU Affero General Public License +# along with this program. If not, see . +# +################################################################################### + +from . import models diff --git a/job_card_management/__manifest__.py b/job_card_management/__manifest__.py new file mode 100644 index 000000000..2d36eff35 --- /dev/null +++ b/job_card_management/__manifest__.py @@ -0,0 +1,50 @@ +# -*- coding: utf-8 -*- +################################################################################### +# Job Card Management +# +# Cybrosys Technologies Pvt. Ltd. +# Copyright (C) 2025-TODAY Cybrosys Technologies (). +# Author: Manasa T P () +# +# This program is free software: you can modify +# it under the terms of the GNU Affero General Public License (AGPL) as +# published by the Free Software Foundation, either version 3 of the +# License, or (at your option) any later version. +# +# 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 for more details. +# +# You should have received a copy of the GNU Affero General Public License +# along with this program. If not, see . +# +################################################################################### +{ + 'name': 'Job Card Management', + 'version': '16.0.1.0.0', + 'category': 'Job Card Management', + 'summary': 'Job Card Management', + 'author': 'Cybrosys Techno Solutions', + 'maintainer': 'Cybrosys Techno Solutions', + 'company': 'Cybrosys Techno Solutions', + 'website': 'https://www.cybrosys.com', + 'description': "Job Card Management", + 'depends': ['hr', 'project', 'purchase', 'account', 'hr_timesheet'], + 'images': ['static/description/banner.png'], + 'data': [ + 'security/ir.model.access.csv', + 'views/job_card_views.xml', + 'views/workshop_views.xml', + 'views/hr_employee_views.xml', + 'views/material_requisition_views.xml', + 'views/job_card_menu_views.xml', + 'data/job_card_data.xml', + 'report/job_card_report.xml', + 'report/cost_sheet.xml' + ], + 'installable': True, + 'application': True, + 'auto_install': False, + 'license': 'AGPL-3', +} diff --git a/job_card_management/data/job_card_data.xml b/job_card_management/data/job_card_data.xml new file mode 100644 index 000000000..c2cdad405 --- /dev/null +++ b/job_card_management/data/job_card_data.xml @@ -0,0 +1,25 @@ + + + + + Job Card Sequence + job.card.sequence + JC + + + + 6 + + + + Material Requisition Sequence + material.requisition.sequence + PMR + + + + 6 + + + + \ No newline at end of file diff --git a/job_card_management/doc/RELEASE_NOTES.md b/job_card_management/doc/RELEASE_NOTES.md new file mode 100644 index 000000000..075dc481d --- /dev/null +++ b/job_card_management/doc/RELEASE_NOTES.md @@ -0,0 +1,8 @@ +## Module + +#### 22.07.2025 +#### Version 16.0.1.0.0 +#### ADD + +- Initial Commit Job Card Management + diff --git a/job_card_management/models/__init__.py b/job_card_management/models/__init__.py new file mode 100644 index 000000000..abb6fec04 --- /dev/null +++ b/job_card_management/models/__init__.py @@ -0,0 +1,28 @@ +# -*- coding: utf-8 -*- +################################################################################### +# Job Card Management +# +# Cybrosys Technologies Pvt. Ltd. +# Copyright (C) 2025-TODAY Cybrosys Technologies (). +# Author: Manasa T P () +# +# This program is free software: you can modify +# it under the terms of the GNU Affero General Public License (AGPL) as +# published by the Free Software Foundation, either version 3 of the +# License, or (at your option) any later version. +# +# 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 for more details. +# +# You should have received a copy of the GNU Affero General Public License +# along with this program. If not, see . +# +################################################################################### + +from . import workshop +from . import hr_employee +from . import job_card +from . import material_requisition +from . import purchase_order diff --git a/job_card_management/models/hr_employee.py b/job_card_management/models/hr_employee.py new file mode 100644 index 000000000..e99268353 --- /dev/null +++ b/job_card_management/models/hr_employee.py @@ -0,0 +1,38 @@ +# -*- coding: utf-8 -*- +################################################################################### +# Job Card Management +# +# Cybrosys Technologies Pvt. Ltd. +# Copyright (C) 2025-TODAY Cybrosys Technologies (). +# Author: Manasa T P () +# +# This program is free software: you can modify +# it under the terms of the GNU Affero General Public License (AGPL) as +# published by the Free Software Foundation, either version 3 of the +# License, or (at your option) any later version. +# +# 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 for more details. +# +# You should have received a copy of the GNU Affero General Public License +# along with this program. If not, see . +# +################################################################################### + +from odoo import models, fields + + +class HrEmployee(models.Model): + """Inherit the model hr employee""" + _inherit = "hr.employee" + + workshop_position = fields.Selection([('leader', 'Leader'), ('worker', 'Worker')], string="Workshop Position") + + +class ProjectTask(models.Model): + _inherit = 'project.task' + + job_card_id = fields.Many2one('job.card', string="Job Card") + diff --git a/job_card_management/models/job_card.py b/job_card_management/models/job_card.py new file mode 100644 index 000000000..1cdd51093 --- /dev/null +++ b/job_card_management/models/job_card.py @@ -0,0 +1,603 @@ +# -*- coding: utf-8 -*- +################################################################################### +# Job Card Management +# +# Cybrosys Technologies Pvt. Ltd. +# Copyright (C) 2025-TODAY Cybrosys Technologies (). +# Author: Manasa T P () +# +# This program is free software: you can modify +# it under the terms of the GNU Affero General Public License (AGPL) as +# published by the Free Software Foundation, either version 3 of the +# License, or (at your option) any later version. +# +# 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 for more details. +# +# You should have received a copy of the GNU Affero General Public License +# along with this program. If not, see . +# +################################################################################### +from werkzeug import urls +from odoo import models, fields, api, _ +from odoo.exceptions import ValidationError + + +class JobCard(models.Model): + """Create new model job card""" + _name = "job.card" + _description = 'Job Card' + + def _default_currency_id(self): + """Return the default currency from the user's company.""" + return self.env.user.company_id.currency_id + + card_name = fields.Char( + string='Job Card Name', + required=True, + help='The name or title of the job card.' + ) + sequence = fields.Char( + string='Sequence', + readonly=True, + help='Unique sequence number for the job card.', + copy = False + ) + name = fields.Char( + string='Reference', + help='Full reference of the job card, combining sequence and name.', + copy=False + ) + + start_date = fields.Date( + string='Start Date', + required=True, + help='The date when the job card starts.' + ) + end_date = fields.Date( + string='End Date', + help='The date when the job card is expected to end.' + ) + project_id = fields.Many2one( + 'project.project', + string='Project', + required=True, + help='The project associated with this job card.' + ) + user_id = fields.Many2one( + 'res.users', + string='Assigned To', + required=True, + help='The user responsible for this job card.' + ) + + quality_checklist_ids = fields.Many2many( + 'quality.check.list', + string='Quality Checklists', + help='List of quality checklists associated with this job card.' + ) + deadline = fields.Date( + string='Deadline', + help='The deadline for completing the job card.' + ) + + team_id = fields.Many2one( + 'workshop.team', + string='Team', + help='The team assigned to this job card.' + ) + currency_id = fields.Many2one( + 'res.currency', + string='Currency', + required=True, + default=lambda self: self._default_currency_id(), + help='The currency used for financial calculations in this job card.' + ) + description = fields.Text( + string='Description', + help='Detailed description of the job card.' + ) + + instruction_ids = fields.One2many( + 'job.card.instruction', + 'job_card_id', + string='Instructions', + help='Instructions associated with this job card.' + ) + instruction_count = fields.Integer( + string='Instruction Count', + default=1, + help='Number of instructions linked to this job card.' + ) + job_cost_sheet_ids = fields.One2many( + 'job.cost.sheet', + 'job_card_id', + string='Cost Sheets', + help='Cost sheets related to this job card.' + ) + cost_sheet_amount = fields.Monetary( + string='Total Cost', + compute='_compute_cost_sheet_amount', + store=True, + help='Total cost calculated from the cost sheets.' + ) + job_cost_sheet_untaxed_amount = fields.Monetary( + string='Untaxed Cost', + compute='_compute_cost_sheet_amount', + store=True, + help='Total untaxed cost calculated from the cost sheets.' + ) + job_card_timesheet_ids = fields.One2many( + 'job.card.timesheet', + 'job_card_id', + string='Timesheets', + help='Timesheet entries for this job card.' + ) + state = fields.Selection( + [ + ('draft', 'Draft'), + ('submit', 'Submitted'), + ('approve', 'Approved'), + ('complete', 'Completed'), + ('invoice', 'Invoiced') + ], + string='Status', + default='draft', + help='Current status of the job card.' + ) + partner_id = fields.Many2one( + 'res.partner', + string='Customer', + required=True, + help='The customer associated with this job card.' + ) + email = fields.Char( + string='Email', + help='Email address for sharing this job card.' + ) + total_hours = fields.Float( + string='Total Working Hours', + compute="_compute_hour", + store=True, + help='Total hours worked on this job card based on timesheets.' + ) + hours = fields.Float( + string='Remaining Hours', + compute="_compute_hour", + store=True, + help='Remaining hours to complete the job card (planned hours minus worked hours).' + ) + planned_hours = fields.Float( + string='Planned Hours', + required=True, + help='Estimated hours required to complete the job card.' + ) + mpr_count = fields.Integer( + string='Material Requisition Count', + compute='compute_count', + help='Number of material requisitions linked to this job card.' + ) + progress = fields.Float( + string='Progress (%)', + help='Percentage of completion based on total hours worked versus planned hours.' + ) + invoice_name = fields.Char( + string='Invoice Reference', + help='Reference number of the invoice generated for this job card.' + ) + invoice_count = fields.Integer( + string='Invoice', + compute='_compute_invoice_count', + help='Number of invoices linked to this job card.' + ) + + @api.model + def create(self, vals): + if not vals.get('sequence'): + vals['sequence'] = self.env['ir.sequence'].next_by_code( + 'job.card.sequence') or '/' + job_card = super(JobCard, self).create(vals) + if job_card.sequence and job_card.card_name: + job_card.name = f"{job_card.sequence}:{job_card.card_name}" + return job_card + + def action_submit(self): + """submit""" + for rec in self: + if not rec.instruction_ids.ids: + raise ValidationError( + 'You cant submit the job card without instruction lines') + else: + rec.state = 'submit' + + def action_approve(self): + """approve, Creating task""" + for rec in self: + if not rec.job_cost_sheet_ids.ids: + raise ValidationError( + 'You cant approve the job card without Cost sheet information') + else: + rec.state = 'approve' + + rec.env['project.task'].create({ + 'name': rec.name, + 'project_id': rec.project_id.id, + 'user_ids': (4, rec.user_id.id), + 'planned_hours': rec.planned_hours, + 'job_card_id': rec.id + }) + + def action_completed(self): + """ complete button """ + for rec in self: + rec.state = 'complete' + + @api.depends('job_card_timesheet_ids.time') + def _compute_hour(self): + """calculate time cost amount""" + for rec in self: + rec.cost_sheet_amount = sum( + rec.job_card_timesheet_ids.mapped('time')) + rec.total_hours = sum( + rec.job_card_timesheet_ids.mapped('time')) + rec.hours = rec.planned_hours - rec.total_hours + + @api.depends('job_cost_sheet_ids.amount') + def _compute_cost_sheet_amount(self): + """calculate time cost amount""" + for rec in self: + rec.cost_sheet_amount = sum(rec.job_cost_sheet_ids.mapped('amount')) + rec.job_cost_sheet_untaxed_amount = sum( + rec.job_cost_sheet_ids.mapped('untaxed_amount')) + + @api.constrains('start_date', 'end_date') + def _date_constrains(self): + """Date validation""" + for rec in self: + if rec.end_date and rec.start_date > rec.end_date: + raise ValidationError( + _('End Date Must be greater Than Start Date...')) + + def create_pmr(self): + """create purchase material request""" + self.ensure_one() + return { + 'type': 'ir.actions.act_window', + 'name': 'PMR', + 'view_mode': 'form', + 'target': 'new', + 'res_model': 'material.requisition', + 'context': { + 'default_job_card_id': self.id + } + } + + def get_pmr(self): + """create purchase material request""" + self.ensure_one() + return { + 'type': 'ir.actions.act_window', + 'name': 'PMR', + 'view_mode': 'tree,form', + 'res_model': 'material.requisition', + 'domain': [('job_card_id', '=', self.id)], + 'context': "{'create': False}" + } + + @api.depends('name') + def compute_count(self): + """Compute mr count""" + for rec in self: + if rec.env['material.requisition'].search( + [('job_card_id', '=', rec.id)]): + rec.mpr_count = rec.env['material.requisition'].search_count( + [('job_card_id', '=', rec.id)]) + else: + rec.mpr_count = 0 + + def create_invoice(self): + """Create invoice""" + lines = [] + for rec in self: + if rec.job_cost_sheet_ids: + for job in rec.job_cost_sheet_ids: + value = (0, 0, { + 'product_id': job.product_id.id, + 'price_unit': job.amount, + 'quantity': job.quantity, + }) + lines.append(value) + invoice_line = { + 'move_type': 'out_invoice', + 'partner_id': rec.partner_id.id, + 'invoice_user_id': rec.env.user.id, + 'invoice_origin': rec.name, + 'ref': rec.name, + 'invoice_line_ids': lines, + } + inv = self.env['account.move'].create(invoice_line) + rec.state = 'invoice' + rec.invoice_name = inv.name + + def _compute_invoice_count(self): + for rec in self: + rec.invoice_count = self.env['account.move'].search_count([ + ('ref', '=', rec.name), + ('move_type', '=', 'out_invoice') + ]) + + def get_invoice(self): + """View the invoice""" + self.ensure_one() + return { + 'type': 'ir.actions.act_window', + 'name': 'Invoice', + 'view_mode': 'tree,form', + 'res_model': 'account.move', + 'domain': [('ref', '=', self.name)], + 'context': "{'create': False}" + } + + @api.onchange('planned_hours', 'total_hours') + def _onchange_progress(self): + """calculate progress""" + if self.planned_hours and self.total_hours: + self.progress = round(100.0 * self.total_hours / self.planned_hours, + 2) + else: + self.progress = 0.0 + + def share(self): + """ when click on share button send mail to partner """ + for rec in self: + base_url = self.env['ir.config_parameter'].sudo().get_param( + 'web.base.url') + Urls = urls.url_join(base_url, + 'web#id=%(id)s&model=job.card&view_type=form' % { + 'id': self.id}) + mail_content = _('Hi %s,
' + 'Job Card' + '' + ) % \ + (rec.partner_id.name, Urls, rec.name) + main_content = { + 'subject': _('Job Card: %s') % self.name, + 'author_id': self.env.user.partner_id.id, + 'body_html': mail_content, + 'email_to': rec.partner_id.email + } + + mail_id = self.env['mail.mail'].create(main_content) + mail_id.mail_message_id.body = mail_content + mail_id.send() + + +class JobCardInstruction(models.Model): + _name = "job.card.instruction" + _description = 'Job Cards Instruction' + _rec_name = 'instruction' + + @api.depends('job_card_id') + def _compute_name(self): + """compute instruction name""" + for rec in self: + name = rec.job_card_id.name + '/' + str( + rec.job_card_id.instruction_count) + if not rec.name: + rec.job_card_id.instruction_count += 1 + rec.name = name + + job_card_id = fields.Many2one( + 'job.card', + string='Job Card', + help='The job card this instruction belongs to.' + ) + name = fields.Char( + string='Instruction Reference', + compute='_compute_name', + store=True, + help='Unique reference for the instruction.' + ) + start_date = fields.Datetime( + string='Start Date', + required=True, + help='The start date and time for this instruction.' + ) + end_date = fields.Datetime( + string='End Date', + help='The end date and time for this instruction.' + ) + user_id = fields.Many2one( + 'res.users', + string='Assigned To', + required=True, + help='The user responsible for executing this instruction.' + ) + instruction = fields.Char( + string='Instruction', + required=True, + help='Details of the instruction to be performed.' + ) + notes = fields.Char( + string='Notes', + help='Additional notes or comments for this instruction.' + ) + state = fields.Selection( + [ + ('to_do', 'To Do'), + ('in_progress', 'In Progress'), + ('done', 'Done') + ], + string='Status', + default='to_do', + help='Current status of the instruction.' + ) + + @api.constrains('start_date', 'end_date') + def _date_constrains(self): + """Date validation""" + for rec in self: + if rec.end_date and rec.start_date > rec.end_date: + raise ValidationError( + _('End Date Must be greater Than Start Date in Job Card Instruction..')) + + +class CostSheet(models.Model): + _name = 'job.cost.sheet' + _description = 'Cost Sheet' + + type = fields.Selection( + [ + ('material', 'Material'), + ('labour', 'Labour'), + ('overhead', 'Overhead') + ], + string='Cost Type', + required=True, + help='The type of cost (material, labour, or overhead).' + ) + job_card_id = fields.Many2one( + 'job.card', + string='Job Card', + help='The job card associated with this cost sheet.' + ) + product_id = fields.Many2one( + 'product.product', + string='Product', + required=True, + help='The product or service related to this cost.' + ) + quantity = fields.Float( + string='Quantity', + default=1, + help='The quantity of the product or service.' + ) + unit_price = fields.Float( + string='Unit Price', + help='The price per unit of the product or service.' + ) + discount = fields.Float( + string='Discount (%)', + help='Discount percentage applied to the cost.' + ) + tax = fields.Many2one( + 'account.tax', + string='Tax', + help='Tax applied to the cost.' + ) + amount = fields.Float( + string='Total Amount', + help='Total amount including taxes after applying discount.' + ) + untaxed_amount = fields.Float( + string='Untaxed Amount', + help='Total amount excluding taxes after applying discount.' + ) + + @api.onchange('product_id', 'discount', 'tax') + def _onchange_product_id(self): + """calculate the amount""" + for rec in self: + rec.unit_price = rec.product_id.list_price + rec.amount = rec.unit_price * rec.quantity + rec.untaxed_amount = rec.unit_price * rec.quantity + if rec.tax: + taxes = rec.tax.compute_all(**rec._prepare_compute_all_values()) + rec.amount = taxes['total_included'] + rec.untaxed_amount = taxes['total_excluded'] + if rec.discount: + rec.amount = rec.amount - (rec.amount * rec.discount / 100) + rec.untaxed_amount = rec.untaxed_amount - ( + rec.untaxed_amount * rec.discount / 100) + + def _prepare_compute_all_values(self): + """prepare values""" + self.ensure_one() + return { + 'price_unit': self.unit_price, + 'currency': self.job_card_id.currency_id, + 'quantity': self.quantity, + 'product': self.product_id, + 'partner': self.job_card_id.user_id.partner_id, + } + + +class JobCardTimesheet(models.Model): + _name = 'job.card.timesheet' + _description = 'Job Card TimeSheet' + + job_card_id = fields.Many2one( + 'job.card', + string='Job Card', + default=lambda self: self._default_job_card_id(), + help='The job card this timesheet entry belongs to.' + ) + name = fields.Char( + string='Timesheet Name', + store=True, + help='Name of the timesheet entry, derived from the instruction.' + ) + instruction_id = fields.Many2one( + 'job.card.instruction', + string='Instruction', + required=True, + help='The instruction associated with this timesheet entry.' + ) + description = fields.Char( + string='Description', + help='Description of the work performed in this timesheet entry.' + ) + leader_id = fields.Many2one( + 'hr.employee', + string='Team Leader', + required=True, + domain=[('workshop_position', '=', 'leader')], + help='The team leader responsible for this timesheet entry.' + ) + worker_id = fields.Many2one( + 'hr.employee', + string='Worker', + required=True, + help='The worker who performed the task in this timesheet entry.' + ) + date = fields.Date( + string='Date', + default=fields.Date.today(), + help='The date when the work was performed.' + ) + time = fields.Float( + string='Hours Worked', + help='Number of hours worked for this timesheet entry.' + ) + + @api.onchange('instruction_id') + def _onchange_instruction_id(self): + """ Add instruction name """ + for rec in self: + if rec.instruction_id: + rec.name = rec.instruction_id.name + ':' + rec.instruction_id.instruction + + @api.model + def create(self, vals_list): + """ create record in account analytic line model """ + res = super(JobCardTimesheet, self).create(vals_list) + job_card = self.env['job.card'].browse(vals_list['job_card_id']) + task = self.env['project.task'].search( + [('job_card_id', '=', job_card.id)]) + self.env['account.analytic.line'].create({ + 'date': vals_list['date'], + 'project_id': job_card.project_id.id, + 'employee_id': vals_list['worker_id'], + 'name': vals_list['description'], + 'unit_amount': vals_list['time'], + 'task_id': task.id + }) + return res diff --git a/job_card_management/models/material_requisition.py b/job_card_management/models/material_requisition.py new file mode 100644 index 000000000..07a8fab8a --- /dev/null +++ b/job_card_management/models/material_requisition.py @@ -0,0 +1,175 @@ +# -*- coding: utf-8 -*- +################################################################################### +# Job Card Management +# +# Cybrosys Technologies Pvt. Ltd. +# Copyright (C) 2025-TODAY Cybrosys Technologies (). +# Author: Manasa T P () +# +# This program is free software: you can modify +# it under the terms of the GNU Affero General Public License (AGPL) as +# published by the Free Software Foundation, either version 3 of the +# License, or (at your option) any later version. +# +# 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 for more details. +# +# You should have received a copy of the GNU Affero General Public License +# along with this program. If not, see . +# +############################################################################### +from odoo.exceptions import ValidationError + +from odoo import models, fields, api + + +class MaterialRequisition(models.Model): + """Create new model material requisition""" + _name = "material.requisition" + _description = "Material Requisition" + + name = fields.Char( + string='Requisition Number', + help='Unique reference number for the material requisition, automatically generated.' + ) + employee_id = fields.Many2one( + comodel_name='hr.employee', + string='Requested By', + required=True, + help='The employee who requested this material requisition.' + ) + department_id = fields.Many2one( + comodel_name='hr.department', + string='Department', + required=True, + help='The department requesting the materials.' + ) + date = fields.Date( + string='Requisition Date', + default=fields.Date.today(), + help='The date when the material requisition was created.' + ) + job_card_id = fields.Many2one( + comodel_name='job.card', + string='Job Card', + help='The job card associated with this material requisition.' + ) + line_ids = fields.One2many( + comodel_name='material.requisition.line', + inverse_name='line_id', + string='Requisition Lines', + help='List of material items requested in this requisition.' + ) + state = fields.Selection( + selection=[ + ('draft', 'Draft'), + ('submit', 'Submitted'), + ('approve', 'Approved'), + ('po', 'Purchase Order') + ], + string='Status', + default='draft', + help='Current status of the material requisition.' + ) + purchase_order_count = fields.Integer( + string="Purchase Orders", + compute="_compute_purchase_order_count" + ) + + @api.model + def create(self, vals_list): + """create sequence""" + sequence_code = 'material.requisition.sequence' + vals_list['name'] = self.env['ir.sequence'].next_by_code(sequence_code) + res = super(MaterialRequisition, self).create(vals_list) + return res + + def action_submit(self): + """submit button""" + for rec in self: + if not rec.line_ids.ids: + raise ValidationError( + 'You cant submit the Material Requisition without requisition lines') + else: + rec.state = 'submit' + + def action_approve(self): + """approve button""" + for rec in self: + rec.state = 'approve' + + def create_purchase_order(self): + """create purchase order""" + for rec in self: + lines = [] + for line in rec.line_ids: + value = (0, 0, { + 'name': line.product_id.name, + 'product_id': line.product_id.id, + 'price_unit': line.product_id.standard_price, + 'product_qty': line.quantity + }) + lines.append(value) + self.env['purchase.order'].create({ + 'partner_id': line.vendor_id.id, + 'order_line': lines, + 'material_requisition_id': rec.id, + }) + rec.state = 'po' + + def _compute_purchase_order_count(self): + for rec in self: + rec.purchase_order_count = self.env[ + 'purchase.order'].search_count([ + ('material_requisition_id', '=', rec.id) + ]) + + def action_view_purchase_orders(self): + self.ensure_one() + return { + 'name': 'Purchase Orders', + 'type': 'ir.actions.act_window', + 'res_model': 'purchase.order', + 'view_mode': 'tree,form', + 'domain': [('material_requisition_id', '=', self.id)], + 'context': {'create': False} + } + + +class MaterialRequisitionLine(models.Model): + _name = "material.requisition.line" + _description = 'Material Requisition Line' + + line_id = fields.Many2one( + comodel_name='material.requisition', + string='Material Requisition', + help='The material requisition this line belongs to.' + ) + name = fields.Char( + string='Description', + help='A brief description of the requisition line.' + ) + product_id = fields.Many2one( + comodel_name='product.product', + string='Product', + required=True, + help='The product or material being requested.' + ) + quantity = fields.Float( + string='Quantity', + required=True, + help='The quantity of the product requested.' + ) + uom = fields.Many2one( + comodel_name='uom.uom', + string='Unit of Measure', + help='The unit of measure for the requested product.' + ) + vendor_id = fields.Many2one( + comodel_name='res.partner', + string='Vendor', + required=True, + help='The vendor from whom the product will be purchased.' + ) diff --git a/job_card_management/models/purchase_order.py b/job_card_management/models/purchase_order.py new file mode 100644 index 000000000..b7258f470 --- /dev/null +++ b/job_card_management/models/purchase_order.py @@ -0,0 +1,30 @@ +# -*- coding: utf-8 -*- +################################################################################### +# Job Card Management +# +# Cybrosys Technologies Pvt. Ltd. +# Copyright (C) 2025-TODAY Cybrosys Technologies (). +# Author: Manasa T P () +# +# This program is free software: you can modify +# it under the terms of the GNU Affero General Public License (AGPL) as +# published by the Free Software Foundation, either version 3 of the +# License, or (at your option) any later version. +# +# 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 for more details. +# +# You should have received a copy of the GNU Affero General Public License +# along with this program. If not, see . +# +############################################################################### + +from odoo import models, fields + +class PurchaseOrder(models.Model): + """Inherit the model purchase order""" + _inherit = 'purchase.order' + + material_requisition_id = fields.Many2one('material.requisition', string="Material Requisition") diff --git a/job_card_management/models/workshop.py b/job_card_management/models/workshop.py new file mode 100644 index 000000000..ddd39e94e --- /dev/null +++ b/job_card_management/models/workshop.py @@ -0,0 +1,55 @@ +# -*- coding: utf-8 -*- +################################################################################### +# Job Card Management +# +# Cybrosys Technologies Pvt. Ltd. +# Copyright (C) 2025-TODAY Cybrosys Technologies (). +# Author: Manasa T P () +# +# This program is free software: you can modify +# it under the terms of the GNU Affero General Public License (AGPL) as +# published by the Free Software Foundation, either version 3 of the +# License, or (at your option) any later version. +# +# 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 for more details. +# +# You should have received a copy of the GNU Affero General Public License +# along with this program. If not, see . +# +################################################################################### + +from odoo import models, fields + + +class WorkshopTeam(models.Model): + _name = 'workshop.team' + _description = 'Workshop Team' + + name = fields.Char( + string='Team Name', + required=True, + help='The name of the workshop team.' + ) + active = fields.Boolean( + string='Active', + default=True, + help='Indicates whether the workshop team is active and available for assignment.' + ) + + +class QualityCheckList(models.Model): + _name = 'quality.check.list' + _description = 'Quality Check List' + + name = fields.Char( + string='Checklist Name', + required=True, + help='The name or title of the quality checklist.' + ) + description = fields.Text( + string='Description', + help='Detailed description of the quality checklist and its purpose.' + ) diff --git a/job_card_management/report/cost_sheet.xml b/job_card_management/report/cost_sheet.xml new file mode 100644 index 000000000..40c8f4b95 --- /dev/null +++ b/job_card_management/report/cost_sheet.xml @@ -0,0 +1,114 @@ + + + + + Cost Sheet + job.card + qweb-pdf + job_card_management.report_cost_sheet + job_card_management.report_cost_sheet + 'Cost Sheet - %s' % object.name + + + report + + + + diff --git a/job_card_management/report/job_card_report.xml b/job_card_management/report/job_card_report.xml new file mode 100644 index 000000000..2e1b9933e --- /dev/null +++ b/job_card_management/report/job_card_report.xml @@ -0,0 +1,197 @@ + + + + + Job Card Report + job.card + qweb-pdf + job_card_management.report_job_card + job_card_management.report_job_card + 'Job card - %s' % object.name + + + report + + + + \ No newline at end of file diff --git a/job_card_management/security/ir.model.access.csv b/job_card_management/security/ir.model.access.csv new file mode 100644 index 000000000..8b61077c7 --- /dev/null +++ b/job_card_management/security/ir.model.access.csv @@ -0,0 +1,9 @@ +id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink +access_workshop_team,workshop.team,model_workshop_team,,1,1,1,1 +access_quality_check_list,quality.check.list,model_quality_check_list,,1,1,1,1 +access_job_card,job.card,model_job_card,,1,1,1,1 +access_job_card_instruction,job.card.instruction,model_job_card_instruction,,1,1,1,1 +access_job_cost_sheet,job.cost.sheet,model_job_cost_sheet,,1,1,1,1 +access_job_card_timesheet,job.card.timesheet,model_job_card_timesheet,,1,1,1,0 +access_material_requisition,material.requisition,model_material_requisition,,1,1,1,1 +access_material_requisition_line,material.requisition.line,model_material_requisition_line,,1,1,1,1 diff --git a/job_card_management/static/description/assets/icons/check.png b/job_card_management/static/description/assets/icons/check.png new file mode 100755 index 000000000..c8e85f51d Binary files /dev/null and b/job_card_management/static/description/assets/icons/check.png differ diff --git a/job_card_management/static/description/assets/icons/chevron.png b/job_card_management/static/description/assets/icons/chevron.png new file mode 100755 index 000000000..2089293d6 Binary files /dev/null and b/job_card_management/static/description/assets/icons/chevron.png differ diff --git a/job_card_management/static/description/assets/icons/cogs.png b/job_card_management/static/description/assets/icons/cogs.png new file mode 100755 index 000000000..95d0bad62 Binary files /dev/null and b/job_card_management/static/description/assets/icons/cogs.png differ diff --git a/job_card_management/static/description/assets/icons/consultation.png b/job_card_management/static/description/assets/icons/consultation.png new file mode 100755 index 000000000..8319d4baa Binary files /dev/null and b/job_card_management/static/description/assets/icons/consultation.png differ diff --git a/job_card_management/static/description/assets/icons/ecom-black.png b/job_card_management/static/description/assets/icons/ecom-black.png new file mode 100755 index 000000000..a9385ff13 Binary files /dev/null and b/job_card_management/static/description/assets/icons/ecom-black.png differ diff --git a/job_card_management/static/description/assets/icons/education-black.png b/job_card_management/static/description/assets/icons/education-black.png new file mode 100755 index 000000000..3eb09b27b Binary files /dev/null and b/job_card_management/static/description/assets/icons/education-black.png differ diff --git a/job_card_management/static/description/assets/icons/hotel-black.png b/job_card_management/static/description/assets/icons/hotel-black.png new file mode 100755 index 000000000..130f613be Binary files /dev/null and b/job_card_management/static/description/assets/icons/hotel-black.png differ diff --git a/job_card_management/static/description/assets/icons/license.png b/job_card_management/static/description/assets/icons/license.png new file mode 100755 index 000000000..a5869797e Binary files /dev/null and b/job_card_management/static/description/assets/icons/license.png differ diff --git a/job_card_management/static/description/assets/icons/lifebuoy.png b/job_card_management/static/description/assets/icons/lifebuoy.png new file mode 100755 index 000000000..658d56ccc Binary files /dev/null and b/job_card_management/static/description/assets/icons/lifebuoy.png differ diff --git a/job_card_management/static/description/assets/icons/manufacturing-black.png b/job_card_management/static/description/assets/icons/manufacturing-black.png new file mode 100755 index 000000000..697eb0e9f Binary files /dev/null and b/job_card_management/static/description/assets/icons/manufacturing-black.png differ diff --git a/job_card_management/static/description/assets/icons/pos-black.png b/job_card_management/static/description/assets/icons/pos-black.png new file mode 100755 index 000000000..97c0f90c1 Binary files /dev/null and b/job_card_management/static/description/assets/icons/pos-black.png differ diff --git a/job_card_management/static/description/assets/icons/puzzle.png b/job_card_management/static/description/assets/icons/puzzle.png new file mode 100755 index 000000000..65cf854e7 Binary files /dev/null and b/job_card_management/static/description/assets/icons/puzzle.png differ diff --git a/job_card_management/static/description/assets/icons/restaurant-black.png b/job_card_management/static/description/assets/icons/restaurant-black.png new file mode 100755 index 000000000..4a35eb939 Binary files /dev/null and b/job_card_management/static/description/assets/icons/restaurant-black.png differ diff --git a/job_card_management/static/description/assets/icons/service-black.png b/job_card_management/static/description/assets/icons/service-black.png new file mode 100755 index 000000000..301ab51cb Binary files /dev/null and b/job_card_management/static/description/assets/icons/service-black.png differ diff --git a/job_card_management/static/description/assets/icons/trading-black.png b/job_card_management/static/description/assets/icons/trading-black.png new file mode 100755 index 000000000..9398ba2f1 Binary files /dev/null and b/job_card_management/static/description/assets/icons/trading-black.png differ diff --git a/job_card_management/static/description/assets/icons/training.png b/job_card_management/static/description/assets/icons/training.png new file mode 100755 index 000000000..884ca024d Binary files /dev/null and b/job_card_management/static/description/assets/icons/training.png differ diff --git a/job_card_management/static/description/assets/icons/update.png b/job_card_management/static/description/assets/icons/update.png new file mode 100755 index 000000000..ecbc5a01a Binary files /dev/null and b/job_card_management/static/description/assets/icons/update.png differ diff --git a/job_card_management/static/description/assets/icons/user.png b/job_card_management/static/description/assets/icons/user.png new file mode 100755 index 000000000..6ffb23d9f Binary files /dev/null and b/job_card_management/static/description/assets/icons/user.png differ diff --git a/job_card_management/static/description/assets/icons/wrench.png b/job_card_management/static/description/assets/icons/wrench.png new file mode 100755 index 000000000..6c04dea0f Binary files /dev/null and b/job_card_management/static/description/assets/icons/wrench.png differ diff --git a/job_card_management/static/description/assets/misc/categories.png b/job_card_management/static/description/assets/misc/categories.png new file mode 100755 index 000000000..bedf1e0b1 Binary files /dev/null and b/job_card_management/static/description/assets/misc/categories.png differ diff --git a/job_card_management/static/description/assets/misc/check-box.png b/job_card_management/static/description/assets/misc/check-box.png new file mode 100755 index 000000000..42caf24b9 Binary files /dev/null and b/job_card_management/static/description/assets/misc/check-box.png differ diff --git a/job_card_management/static/description/assets/misc/compass.png b/job_card_management/static/description/assets/misc/compass.png new file mode 100755 index 000000000..d5fed8faa Binary files /dev/null and b/job_card_management/static/description/assets/misc/compass.png differ diff --git a/job_card_management/static/description/assets/misc/corporate.png b/job_card_management/static/description/assets/misc/corporate.png new file mode 100755 index 000000000..2eb13edbf Binary files /dev/null and b/job_card_management/static/description/assets/misc/corporate.png differ diff --git a/job_card_management/static/description/assets/misc/customer-support.png b/job_card_management/static/description/assets/misc/customer-support.png new file mode 100755 index 000000000..79efc72ed Binary files /dev/null and b/job_card_management/static/description/assets/misc/customer-support.png differ diff --git a/job_card_management/static/description/assets/misc/cybrosys-logo.png b/job_card_management/static/description/assets/misc/cybrosys-logo.png new file mode 100755 index 000000000..cc3cc0ccf Binary files /dev/null and b/job_card_management/static/description/assets/misc/cybrosys-logo.png differ diff --git a/job_card_management/static/description/assets/misc/features.png b/job_card_management/static/description/assets/misc/features.png new file mode 100755 index 000000000..b41769f77 Binary files /dev/null and b/job_card_management/static/description/assets/misc/features.png differ diff --git a/job_card_management/static/description/assets/misc/logo.png b/job_card_management/static/description/assets/misc/logo.png new file mode 100755 index 000000000..478462d3e Binary files /dev/null and b/job_card_management/static/description/assets/misc/logo.png differ diff --git a/job_card_management/static/description/assets/misc/pictures.png b/job_card_management/static/description/assets/misc/pictures.png new file mode 100755 index 000000000..56d255fe9 Binary files /dev/null and b/job_card_management/static/description/assets/misc/pictures.png differ diff --git a/job_card_management/static/description/assets/misc/pie-chart.png b/job_card_management/static/description/assets/misc/pie-chart.png new file mode 100755 index 000000000..426e05244 Binary files /dev/null and b/job_card_management/static/description/assets/misc/pie-chart.png differ diff --git a/job_card_management/static/description/assets/misc/right-arrow.png b/job_card_management/static/description/assets/misc/right-arrow.png new file mode 100755 index 000000000..730984a06 Binary files /dev/null and b/job_card_management/static/description/assets/misc/right-arrow.png differ diff --git a/job_card_management/static/description/assets/misc/star.png b/job_card_management/static/description/assets/misc/star.png new file mode 100755 index 000000000..2eb9ab29f Binary files /dev/null and b/job_card_management/static/description/assets/misc/star.png differ diff --git a/job_card_management/static/description/assets/misc/support.png b/job_card_management/static/description/assets/misc/support.png new file mode 100755 index 000000000..4f18b8b82 Binary files /dev/null and b/job_card_management/static/description/assets/misc/support.png differ diff --git a/job_card_management/static/description/assets/misc/whatsapp.png b/job_card_management/static/description/assets/misc/whatsapp.png new file mode 100755 index 000000000..d513a5356 Binary files /dev/null and b/job_card_management/static/description/assets/misc/whatsapp.png differ diff --git a/job_card_management/static/description/assets/modules/1.png b/job_card_management/static/description/assets/modules/1.png new file mode 100644 index 000000000..5ecc4d883 Binary files /dev/null and b/job_card_management/static/description/assets/modules/1.png differ diff --git a/job_card_management/static/description/assets/modules/2.png b/job_card_management/static/description/assets/modules/2.png new file mode 100644 index 000000000..d1d3775d6 Binary files /dev/null and b/job_card_management/static/description/assets/modules/2.png differ diff --git a/job_card_management/static/description/assets/modules/3.png b/job_card_management/static/description/assets/modules/3.png new file mode 100644 index 000000000..dcbd0cb06 Binary files /dev/null and b/job_card_management/static/description/assets/modules/3.png differ diff --git a/job_card_management/static/description/assets/modules/4.png b/job_card_management/static/description/assets/modules/4.png new file mode 100644 index 000000000..fd1f87699 Binary files /dev/null and b/job_card_management/static/description/assets/modules/4.png differ diff --git a/job_card_management/static/description/assets/modules/5.png b/job_card_management/static/description/assets/modules/5.png new file mode 100644 index 000000000..05c8b4a69 Binary files /dev/null and b/job_card_management/static/description/assets/modules/5.png differ diff --git a/job_card_management/static/description/assets/modules/6.png b/job_card_management/static/description/assets/modules/6.png new file mode 100644 index 000000000..f5c24146b Binary files /dev/null and b/job_card_management/static/description/assets/modules/6.png differ diff --git a/job_card_management/static/description/assets/screenshots/1.png b/job_card_management/static/description/assets/screenshots/1.png new file mode 100644 index 000000000..c9e373a2e Binary files /dev/null and b/job_card_management/static/description/assets/screenshots/1.png differ diff --git a/job_card_management/static/description/assets/screenshots/10.png b/job_card_management/static/description/assets/screenshots/10.png new file mode 100644 index 000000000..21b93ff10 Binary files /dev/null and b/job_card_management/static/description/assets/screenshots/10.png differ diff --git a/job_card_management/static/description/assets/screenshots/11.png b/job_card_management/static/description/assets/screenshots/11.png new file mode 100644 index 000000000..7a8e87dca Binary files /dev/null and b/job_card_management/static/description/assets/screenshots/11.png differ diff --git a/job_card_management/static/description/assets/screenshots/12.png b/job_card_management/static/description/assets/screenshots/12.png new file mode 100644 index 000000000..3f6918c47 Binary files /dev/null and b/job_card_management/static/description/assets/screenshots/12.png differ diff --git a/job_card_management/static/description/assets/screenshots/13.png b/job_card_management/static/description/assets/screenshots/13.png new file mode 100644 index 000000000..d75cb47ad Binary files /dev/null and b/job_card_management/static/description/assets/screenshots/13.png differ diff --git a/job_card_management/static/description/assets/screenshots/14.png b/job_card_management/static/description/assets/screenshots/14.png new file mode 100644 index 000000000..9ac3a1f7c Binary files /dev/null and b/job_card_management/static/description/assets/screenshots/14.png differ diff --git a/job_card_management/static/description/assets/screenshots/15.png b/job_card_management/static/description/assets/screenshots/15.png new file mode 100644 index 000000000..f06e57af8 Binary files /dev/null and b/job_card_management/static/description/assets/screenshots/15.png differ diff --git a/job_card_management/static/description/assets/screenshots/16.png b/job_card_management/static/description/assets/screenshots/16.png new file mode 100644 index 000000000..81c1fac93 Binary files /dev/null and b/job_card_management/static/description/assets/screenshots/16.png differ diff --git a/job_card_management/static/description/assets/screenshots/17.png b/job_card_management/static/description/assets/screenshots/17.png new file mode 100644 index 000000000..928d53ead Binary files /dev/null and b/job_card_management/static/description/assets/screenshots/17.png differ diff --git a/job_card_management/static/description/assets/screenshots/2.png b/job_card_management/static/description/assets/screenshots/2.png new file mode 100644 index 000000000..aac477722 Binary files /dev/null and b/job_card_management/static/description/assets/screenshots/2.png differ diff --git a/job_card_management/static/description/assets/screenshots/3.png b/job_card_management/static/description/assets/screenshots/3.png new file mode 100644 index 000000000..3159c301e Binary files /dev/null and b/job_card_management/static/description/assets/screenshots/3.png differ diff --git a/job_card_management/static/description/assets/screenshots/4.png b/job_card_management/static/description/assets/screenshots/4.png new file mode 100644 index 000000000..a919ea081 Binary files /dev/null and b/job_card_management/static/description/assets/screenshots/4.png differ diff --git a/job_card_management/static/description/assets/screenshots/5.png b/job_card_management/static/description/assets/screenshots/5.png new file mode 100644 index 000000000..0a2180b74 Binary files /dev/null and b/job_card_management/static/description/assets/screenshots/5.png differ diff --git a/job_card_management/static/description/assets/screenshots/6.png b/job_card_management/static/description/assets/screenshots/6.png new file mode 100644 index 000000000..30e1177d6 Binary files /dev/null and b/job_card_management/static/description/assets/screenshots/6.png differ diff --git a/job_card_management/static/description/assets/screenshots/7.png b/job_card_management/static/description/assets/screenshots/7.png new file mode 100644 index 000000000..82d96a053 Binary files /dev/null and b/job_card_management/static/description/assets/screenshots/7.png differ diff --git a/job_card_management/static/description/assets/screenshots/8.png b/job_card_management/static/description/assets/screenshots/8.png new file mode 100644 index 000000000..49ba181a6 Binary files /dev/null and b/job_card_management/static/description/assets/screenshots/8.png differ diff --git a/job_card_management/static/description/assets/screenshots/9.png b/job_card_management/static/description/assets/screenshots/9.png new file mode 100644 index 000000000..73fb89394 Binary files /dev/null and b/job_card_management/static/description/assets/screenshots/9.png differ diff --git a/job_card_management/static/description/assets/screenshots/hero.gif b/job_card_management/static/description/assets/screenshots/hero.gif new file mode 100644 index 000000000..a8720b896 Binary files /dev/null and b/job_card_management/static/description/assets/screenshots/hero.gif differ diff --git a/job_card_management/static/description/banner.png b/job_card_management/static/description/banner.png new file mode 100644 index 000000000..eb65f7f87 Binary files /dev/null and b/job_card_management/static/description/banner.png differ diff --git a/job_card_management/static/description/icon.png b/job_card_management/static/description/icon.png new file mode 100644 index 000000000..ae5b22a80 Binary files /dev/null and b/job_card_management/static/description/icon.png differ diff --git a/job_card_management/static/description/index.html b/job_card_management/static/description/index.html new file mode 100644 index 000000000..bda50924c --- /dev/null +++ b/job_card_management/static/description/index.html @@ -0,0 +1,748 @@ +
+ +
+ +
+
+ Community +
+
+ Enterprise +
+
+
+ +
+
+
+ +

+ Job Card Management

+

+ A Module For Managing All Job orders +

+ + +
+
+
+
+ + +
+
+ +
+

+ Explore This + Module

+
+ + + + +
+
+ +
+

+ Overview +

+
+
+
+ This module helps you to manage all job orders Workshops, Factory, Any + Technical, Repair Shops, Industry.It is a used to manage all aspects of + your job card operations. +
+
+ + + +
+
+ +
+

+ Features +

+
+
+
+
+ + Configure Job cards +
+
+ + Configure the workshop team +
+
+ + Configure workshop positions +
+
+ + Manage project and task +
+
+ + Product material request +
+
+ + Job Card Reports +
+
+ + Cash Sheet report +
+
+ + + Available in Odoo 16.0 Community and Enterprise. +
+
+
+ + + +
+
+ +
+

+ Screenshots +

+
+ +
+
+ +
+

+ Job Card

+ +

After installation, navigate to the Job Card app and create job cards. +

+ + +
+ +
+

+ Instructions

+

Add the instruction lines. +

+ +
+ +
+

+ Cost Sheet

+

+ Add the cost sheet for this job card. +

+ +
+
+

+ Job Card Timesheet

+

To submit and approve those job card we have some buttons. After + approve this job card we can create the timesheet for this job + card.

+ +
+
+

+ Timesheet

+

+ Create the timesheet, where you can also view the total hours worked and the progress. +

+ +
+
+

+ Extra information

+

+ Customer details and the pending work hours. +

+ +
+
+

+ Purchase Material Request

+

+ Create the PMR by clicking this button +

+ + + +
+
+

+ Create Invoice

+

+ By click the complete button the state changed to 'Completed'. + Then we can see the button to create Invoice. View the Invoice + from the smart button +

+ +
+
+

+ Share The Job Card

+

+ By click the share button we can share this job card with our + customer. +

+ +
+
+

+ Job Card report

+

+ By click this button we get the job card report. +

+ + +
+
+

+ Cost Sheet report

+

+ By click this button we get the cost sheet report. +

+ +
+
+

+ Task

+

+ When we approve our job card it automatically create a task. +

+ +
+
+

+ Workshop Team

+ +
+
+

+ Workshop position

+ +
+
+

+ Quality CheckList

+ +
+ +
+
+ + + + +
+
+ +
+

+ Related + Products +

+
+
+
+ +
+
+ + + + +
+
+ +
+

+ Our Services +

+
+ +
+
+
+
+ +
+
+ Odoo + Customization
+
+ +
+
+ +
+
+ Odoo + Implementation
+
+ +
+
+ +
+
+ Odoo + Support
+
+ + +
+
+ +
+
+ Hire + Odoo + Developer
+
+ +
+
+ +
+
+ Odoo + Integration
+
+ +
+
+ +
+
+ Odoo + Migration
+
+ + +
+
+ +
+
+ Odoo + Consultancy
+
+ +
+
+ +
+
+ Odoo + Implementation
+
+ +
+
+ +
+
+ Odoo + Licensing Consultancy
+
+
+ +
+ + + + + +
+
+ +
+

+ Our + Industries +

+
+ +
+
+
+
+ +
+ Trading +
+

+ Easily procure + and + sell your products

+
+
+ +
+
+ +
+ POS +
+

+ Easy + configuration + and convivial experience

+
+
+ +
+
+ +
+ Education +
+

+ A platform for + educational management

+
+
+ +
+
+ +
+ Manufacturing +
+

+ Plan, track and + schedule your operations

+
+
+ +
+
+ +
+ E-commerce & Website +
+

+ Mobile + friendly, + awe-inspiring product pages

+
+
+ +
+
+ +
+ Service Management +
+

+ Keep track of + services and invoice

+
+
+ +
+
+ +
+ Restaurant +
+

+ Run your bar or + restaurant methodically

+
+
+ +
+
+ +
+ Hotel Management +
+

+ An + all-inclusive + hotel management application

+
+
+
+
+ + + + +
+
+ +
+

+ Support +

+
+
+
+
+
+
+ +
+
+

Need Help?

+

Got questions or need help? + Get in touch.

+ +

+ odoo@cybrosys.com

+
+
+
+
+
+
+
+ +
+
+

WhatsApp

+

Say hi to us on WhatsApp!

+ +

+ +91 86068 + 27707

+
+
+
+
+
+
+
+ +
+
+
+ \ No newline at end of file diff --git a/job_card_management/views/hr_employee_views.xml b/job_card_management/views/hr_employee_views.xml new file mode 100644 index 000000000..3905584e5 --- /dev/null +++ b/job_card_management/views/hr_employee_views.xml @@ -0,0 +1,27 @@ + + + + + hr.employee.form + hr.employee + + + + + + + + + + project.task.form + project.task + + + + + + + + + + \ No newline at end of file diff --git a/job_card_management/views/job_card_menu_views.xml b/job_card_management/views/job_card_menu_views.xml new file mode 100644 index 000000000..2afaad8a0 --- /dev/null +++ b/job_card_management/views/job_card_menu_views.xml @@ -0,0 +1,26 @@ + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/job_card_management/views/job_card_views.xml b/job_card_management/views/job_card_views.xml new file mode 100644 index 000000000..2bd7bbe61 --- /dev/null +++ b/job_card_management/views/job_card_views.xml @@ -0,0 +1,177 @@ + + + + + job.card.view.tree + job.card + + + + + + + + + + + + + + + job.card.view.form + job.card + +
+
+
+ +
+ + + +
+
+

+ + +

+

+ +

+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+ +
+
+ +
+
+ + + + + + + + + + + + + + + + + + + + + + +
+
+ +
+ +
+ + + + + + + + + + + + +
+
+
+
+
+ + + Job Card + ir.actions.act_window + job.card + tree,form + +

+ Define a new Job Card +

+
+
+ +
+
\ No newline at end of file diff --git a/job_card_management/views/material_requisition_views.xml b/job_card_management/views/material_requisition_views.xml new file mode 100644 index 000000000..73f3b60fe --- /dev/null +++ b/job_card_management/views/material_requisition_views.xml @@ -0,0 +1,90 @@ + + + + + material.requisition.tree + material.requisition + + + + + + + + + + + + material.requisition.form + material.requisition + +
+
+
+ +
+ +
+
+

+ +

+
+ + + + + + + + + + + + + + + + + + + + + + + +
+
+
+
+ + + Material Requisition Action + ir.actions.act_window + material.requisition + tree,form + +

+ Define a new Material Requisition +

+
+
+
+
\ No newline at end of file diff --git a/job_card_management/views/workshop_views.xml b/job_card_management/views/workshop_views.xml new file mode 100644 index 000000000..328c8fe4c --- /dev/null +++ b/job_card_management/views/workshop_views.xml @@ -0,0 +1,68 @@ + + + + + + workshop.team.tree.view + workshop.team + + + + + + + + + + Workshop Team + ir.actions.act_window + workshop.team + tree + +

+ Define a new Team +

+
+
+ + + quality.check.list.tree.view + quality.check.list + + + + + + + + + + quality.check.list.form.view + quality.check.list + +
+ + + + + + + +
+
+
+ + + Quality Checklist + ir.actions.act_window + quality.check.list + tree,form + +

+ Define a new Quality CheckList +

+
+
+ +
+
\ No newline at end of file