diff --git a/fleet_car_workshop/README.rst b/fleet_car_workshop/README.rst new file mode 100644 index 000000000..2a85f4cc1 --- /dev/null +++ b/fleet_car_workshop/README.rst @@ -0,0 +1,18 @@ +Car Workshop v16 +================ +Car Workshop Management helps to manage automobile workshop with +great ease. Keep track of everything, like vehicle owner details, +Works assigned, Bill details of service provided, etc. + +Features +======== +* User Friendly Interface. +* Effective Time management. +* Separate Journal Configuration. +* Integrated with Accounting. +* High Scalability. + + .. note:: + + # Its Working Domain Based on Project App. + # Mapped Fleet for Easy Method. diff --git a/fleet_car_workshop/__init__.py b/fleet_car_workshop/__init__.py new file mode 100644 index 000000000..17e164218 --- /dev/null +++ b/fleet_car_workshop/__init__.py @@ -0,0 +1,21 @@ +# -*- coding: utf-8 -*- +############################################################################## +# +# Cybrosys Technologies Pvt. Ltd. +# Copyright (C) 2022-TODAY Cybrosys Technologies(). +# Author: ASWATHI C () +# you can modify it under the terms of the GNU LESSER +# GENERAL PUBLIC LICENSE (LGPL 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 LESSER GENERAL PUBLIC LICENSE (LGPL v3) for more details. +# +# You should have received a copy of the GNU LESSER GENERAL PUBLIC LICENSE +# GENERAL PUBLIC LICENSE (LGPL v3) along with this program. +# If not, see . +# +############################################################################## +from . import models + diff --git a/fleet_car_workshop/__manifest__.py b/fleet_car_workshop/__manifest__.py new file mode 100644 index 000000000..7fc26fed8 --- /dev/null +++ b/fleet_car_workshop/__manifest__.py @@ -0,0 +1,54 @@ +# -*- coding: utf-8 -*- +############################################################################## +# +# Cybrosys Technologies Pvt. Ltd. +# Copyright (C) 2022-TODAY Cybrosys Technologies(). +# Author: ASWATHI C () +# you can modify it under the terms of the GNU LESSER +# GENERAL PUBLIC LICENSE (LGPL 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 LESSER GENERAL PUBLIC LICENSE (LGPL v3) for more details. +# +# You should have received a copy of the GNU LESSER GENERAL PUBLIC LICENSE +# GENERAL PUBLIC LICENSE (LGPL v3) along with this program. +# If not, see . +# +############################################################################## +{ + 'name': 'Car Workshop', + 'version': '16.0.1.0.0', + 'summary': 'Complete Vehicle Workshop Operations & Reports', + 'description': 'Vehicle workshop operations & Its reports', + 'category': 'Industries', + 'author': 'Cybrosys Techno Solutions', + 'website': "https://www.cybrosys.com", + 'company': 'Cybrosys Techno Solutions', + 'depends': [ + 'base', + 'fleet', + 'stock', 'account' + ], + 'data': [ + 'data/workshop_data.xml', + 'views/worksheet_views.xml', + 'views/configuration_settings_view.xml', + 'views/car_dashboard.xml', + 'views/timesheet_view.xml', + 'views/worksheet_stages.xml', + 'views/report.xml', + 'security/workshop_security.xml', + 'security/ir.model.access.csv', + ], + 'web.assets_backend': [ + 'fleet_car_workshop/static/src/css/vehicles.css', + 'fleet_car_workshop/static/src/less/car_dashboard.less', + ], + 'images': ['static/description/banner.png'], + 'license': 'AGPL-3', + 'installable': True, + 'auto_install': False, + 'application': False, +} diff --git a/fleet_car_workshop/data/workshop_data.xml b/fleet_car_workshop/data/workshop_data.xml new file mode 100644 index 000000000..ef24f427e --- /dev/null +++ b/fleet_car_workshop/data/workshop_data.xml @@ -0,0 +1,77 @@ + + + + + + + + + + + + + + + + + + + Task Opened + car.workshop + + + Task opened + + + Task Blocked + car.workshop + + Task blocked + + + Task Ready + car.workshop + + Task ready for Next Stage + + + Stage Changed + car.workshop + + Stage changed + + + + Task Opened + 10 + car.car + + + vehicle_id + + + Task Blocked + 11 + car.car + + + vehicle_id + + + Task Ready + 12 + car.car + + + vehicle_id + + + Task Stage Changed + 13 + car.car + + + vehicle_id + + + \ No newline at end of file diff --git a/fleet_car_workshop/doc/RELEASE_NOTES.md b/fleet_car_workshop/doc/RELEASE_NOTES.md new file mode 100755 index 000000000..a0f279641 --- /dev/null +++ b/fleet_car_workshop/doc/RELEASE_NOTES.md @@ -0,0 +1,10 @@ +## Module + +#### 5.11.2022 +#### Version 16.0.1.0.0 +#### ADD +Initial Commit + + + + diff --git a/fleet_car_workshop/models/__init__.py b/fleet_car_workshop/models/__init__.py new file mode 100644 index 000000000..9f699dba6 --- /dev/null +++ b/fleet_car_workshop/models/__init__.py @@ -0,0 +1,23 @@ +# -*- coding: utf-8 -*- +############################################################################## +# +# Cybrosys Technologies Pvt. Ltd. +# Copyright (C) 2022-TODAY Cybrosys Technologies(). +# Author: ASWATHI C () +# you can modify it under the terms of the GNU LESSER +# GENERAL PUBLIC LICENSE (LGPL 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 LESSER GENERAL PUBLIC LICENSE (LGPL v3) for more details. +# +# You should have received a copy of the GNU LESSER GENERAL PUBLIC LICENSE +# GENERAL PUBLIC LICENSE (LGPL v3) along with this program. +# If not, see . +# +############################################################################## +from . import car_workshop +from . import timesheet +from . import dashboard +from . import config diff --git a/fleet_car_workshop/models/car_workshop.py b/fleet_car_workshop/models/car_workshop.py new file mode 100644 index 000000000..9b99538e6 --- /dev/null +++ b/fleet_car_workshop/models/car_workshop.py @@ -0,0 +1,431 @@ +# -*- coding: utf-8 -*- +############################################################################## +# +# Cybrosys Technologies Pvt. Ltd. +# Copyright (C) 2022-TODAY Cybrosys Technologies(). +# Author: ASWATHI C () +# you can modify it under the terms of the GNU LESSER +# GENERAL PUBLIC LICENSE (LGPL 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 LESSER GENERAL PUBLIC LICENSE (LGPL v3) for more details. +# +# You should have received a copy of the GNU LESSER GENERAL PUBLIC LICENSE +# GENERAL PUBLIC LICENSE (LGPL v3) along with this program. +# If not, see . +# +############################################################################## +from datetime import date, datetime +from dateutil.relativedelta import relativedelta +from psutil import long + +from odoo.exceptions import UserError +from odoo import models, api, fields, _ + + +class CarWorkshop(models.Model): + _name = 'car.workshop' + _description = "Car Workshop" + _inherit = ['mail.thread'] + + def _get_default_vehicle(self): + car_id = self._context.get('active_id') + car = self.env['car.car'].browse(car_id) + if car.name: + return car.name.id + else: + return 1 + + vehicle_id = fields.Many2one('car.car', string='Vehicle', + default=lambda self: self.env.context.get('default_vehicle_id'), index=True, + tracking=True, + change_default=True) + + + @api.model + def _default_company_id(self): + car_id = self._context.get('active_id') + car = self.env['car.car'].browse(car_id) + if car.vehicle_id: + return car.vehicle_id.company_id.id + else: + return self.env.company + + def _get_default_partner(self): + if 'default_vehicle_id' in self.env.context: + default_vehicle_id = self.env['car.car'].browse(self.env.context['default_vehicle_id']) + return default_vehicle_id.partner_id + + def _get_default_stage_id(self): + """ Gives default stage_id """ + vehicle_id = self.env.context.get('default_vehicle_id') + if not vehicle_id: + return False + return self.stage_find(vehicle_id, [('fold', '=', False)]) + + + @api.model + def _read_group_stage_ids(self, stages, domain, order): + search_domain = [('id', 'in', stages.ids)] + if 'default_vehicle_id' in self.env.context: + search_domain = ['|', ('vehicle_ids', '=', self.env.context['default_vehicle_id'])] + search_domain + + stage_ids = stages._search(search_domain, order=order) + return stages.browse(stage_ids) + + name = fields.Char(string='Title', track_visibility='onchange', required=True) + user_id = fields.Many2one('res.users', string='Assigned to', default=lambda self: self.env.user, tracking=True) + active = fields.Boolean(string='Active', default=True) + partner_id = fields.Many2one('res.partner', string='Customer', default=_get_default_partner) + priority = fields.Selection([('0', 'Normal'), ('1', 'High')], 'Priority', select=True, default='0') + description = fields.Html(string='Description') + sequence = fields.Integer(string='Sequence', select=True, default=10, + help="Gives the sequence order when displaying a list of tasks.") + tag_ids = fields.Many2many('worksheet.tags', string='Tags', ondelete='cascade') + kanban_state = fields.Selection( + [('normal', 'In Progress'), ('done', 'Ready for next stage'), ('blocked', 'Blocked')], 'Kanban State', + help="A task's kanban state indicates special situations affecting it:\n" + " * Normal is the default situation\n" + " * Blocked indicates something is preventing the progress of this task\n" + " * Ready for next stage indicates the task is ready to be pulled to the next stage", + required=True, track_visibility='onchange', default='normal', copy=False) + create_date = fields.Datetime(string='Create Date', readonly=True, select=True) + write_date = fields.Datetime(string='Last Modification Date', readonly=True, select=True) + date_start = fields.Datetime(string='Starting Date', default=fields.datetime.now(), select=True, copy=False) + date_end = fields.Datetime(string='Ending Date', select=True, copy=False) + date_assign = fields.Datetime(string='Assigning Date', select=True, copy=False) + date_deadline = fields.Datetime(string='Deadline', select=True, copy=False) + progress = fields.Integer(string="Working Time Progress(%)", copy=False, readonly=True) + date_last_stage_update = fields.Datetime(string='Last Stage Update', select=True, default=fields.datetime.now(), + copy=False, readonly=True) + id = fields.Integer('ID', readonly=True) + company_id = fields.Many2one('res.company', string='Company', required=True, default=_default_company_id) + + # company_id = fields.Many2many('res.company', string='Company Name', default=lambda self: self.env['res.company']._company_default_get('car.workshop')) + color = fields.Integer(string='Color Index') + stage_id = fields.Many2one('worksheet.stages', string='Stage', ondelete='restrict', tracking=True, index=True, + default=_get_default_stage_id, group_expand='_read_group_stage_ids', + domain="[('vehicle_ids', '=', vehicle_id)]", copy=False) + + # stage_id = fields.Many2one('project.task.type', string='Stage', ondelete='restrict', tracking=True, index=True, + # default=_get_default_stage_id, group_expand='_read_group_stage_ids', + # domain="[('project_ids', '=', project_id)]", copy=False) + + state = fields.Selection([ + ('waiting', 'Ready'), + ('workshop_create_invoices', 'Invoiced'), + ('cancel', 'Invoice Canceled'), + ], string='Status', readonly=True, default='waiting', track_visibility='onchange', select=True) + attachment_ids = fields.One2many('ir.attachment', 'res_id', domain=lambda self: [('res_model', '=', self._name)], + auto_join=True, string='Attachments') + displayed_image_id = fields.Many2one('ir.attachment', + domain="[" + "('res_model', '=', 'car.workshop')," + "('res_id', '=', id)," + "('mimetype', 'ilike', 'image')]", + string='Displayed Image') + planned_works = fields.One2many('planned.work', 'work_id', string='Planned/Ordered Works') + works_done = fields.One2many('planned.work', 'work_id', string='Work Done', domain=[('completed', '=', True)]) + materials_used = fields.One2many('material.used', 'material_id', string='Materials Used') + remaining_hour = fields.Float(string='Remaining Hour', readonly=True, compute="hours_left") + effective_hour = fields.Float(string='Hours Spent', readonly=True, compute="hours_spent") + amount_total = fields.Float(string='Total Amount', readonly=True, compute="amount_total1") + + invoice_count = fields.Integer(string="Invoice_count", compute='compute_invoice_count') + + + @api.depends('planned_works.work_cost', 'materials_used.price') + def amount_total1(self): + for records in self: + for hour in records: + amount_totall = 0.0 + for line in hour.planned_works: + amount_totall += line.work_cost + for line2 in hour.materials_used: + amount_totall += line2.price + records.amount_total = amount_totall + + def cancel(self): + self.state = 'cancel' + + def workshop_create_invoices(self): + print(self.planned_works.planned_work.property_account_income_id,'rrrrrrrrrrrrrrrrrrrrrrrrr') + self.state = 'workshop_create_invoices' + inv_obj = self.env['account.move'] + print('inv_obj',inv_obj) + inv_line_obj = self.env['account.move.line'] + customer = self.partner_id + if not customer.name: + raise UserError( + _( + 'Please select a Customer.')) + + + invoice_line_ids = [] + company_id = self.env['res.users'].browse(1).company_id + currency_value = company_id.currency_id.id + self.ensure_one() + journal_id = self.env['ir.config_parameter'].sudo().get_param( + 'fleet_car_workshop.invoice_journal_type') + print(journal_id,'journal_id') + if not journal_id: + journal_id = 1 + + inv_data = { + 'ref': self.name, + 'partner_bank_id': customer.bank_ids[:1].id, + 'partner_id': customer.id, + 'currency_id': currency_value, + 'journal_id': int(journal_id), + 'invoice_origin': self.name, + 'company_id': company_id.id, + 'move_type': 'out_invoice', + # 'invoice_line_ids': invoice_line_ids, + } + + for records in self.planned_works: + if records.planned_work.id: + income_account = records.planned_work.property_account_income_id.id + inv_line_data = (0, 0, { + 'name': records.planned_work.name, + 'account_id': income_account, + 'price_unit': records.work_cost, + 'quantity': 1, + 'product_id': records.planned_work.id, + }) + invoice_line_ids.append(inv_line_data) + if not income_account: + raise UserError(_('There is no income account defined for this product: "%s".') % + (records.planned_work.name,)) + + for records in self.materials_used: + if records.material.id: + income_account = records.material.property_account_income_id.id + inv_line_data = (0, 0, { + 'name': records.material.name, + 'account_id': records.material.property_account_income_id.id, + 'price_unit': records.price, + 'quantity': records.amount, + 'product_id': records.material.id, + }) + invoice_line_ids.append(inv_line_data) + if not income_account: + raise UserError(_('There is no income account defined for this product: "%s".') % + (records.material.name,)) + + inv_data.update({ + 'invoice_line_ids': invoice_line_ids + }) + inv_id = inv_obj.create(inv_data) + result = { + 'type': 'ir.actions.act_window', + 'name': _('Invoice'), + 'view_mode': 'form', + 'res_model': 'account.move', + 'target': 'current', + 'res_id': inv_id.id, + } + IMD = self.env['ir.model.data'] + form_view_id = IMD._xmlid_to_res_id('account.invoice_form') + if len(inv_id) > 1: + result['domain'] = "[('id','in',%s)]" % inv_id.ids + elif len(inv_id) == 1: + result['views'] = [(form_view_id, 'form')] + result['res_id'] = inv_id.ids[0] + else: + result = {'type': 'ir.actions.act_window_close'} + invoiced_records = self.env['car.workshop'] + + total = 0 + for rows in invoiced_records: + invoiced_date = rows.date + invoiced_date = invoiced_date[0:10] + if invoiced_date == str(date.today()): + total = total + rows.price_subtotal + for lines in self.materials_used: + product_ids = self.env['product.product'].search( + [('id', '=', lines.material.id)]) + for prod_id in product_ids: + move_id = self.env['stock.picking'] + type_object = self.env['stock.picking.type'] + company_id = self.env.context.get('company_id') or self.env.user.company_id.id + types = type_object.search([('code', '=', 'outgoing'), ('warehouse_id.company_id', '=', company_id)], + limit=1) + vals = { + 'partner_id': self.partner_id.id, + 'origin': self.name, + 'move_type': 'one', + 'picking_type_id': types.id, + 'location_id': types.default_location_src_id.id, + 'location_dest_id': self.partner_id.property_stock_customer.id, + 'move_ids': [(0, 0, { + 'name': self.name, + 'product_id': prod_id.id, + 'product_uom': prod_id.uom_id.id, + 'product_uom_qty': lines.amount, + 'quantity_done': lines.amount, + 'location_id': types.default_location_src_id.id, + 'location_dest_id': self.partner_id.property_stock_customer.id, + })], + } + move = move_id.create(vals) + move.action_confirm() + move.action_assign() + move._action_done() + return result + + @api.depends('works_done.duration') + def hours_spent(self): + for hour in self: + effective_hour = 0.0 + for line in hour.works_done: + effective_hour += line.duration + self.effective_hour = effective_hour + + @api.depends('planned_works.time_spent') + def hours_left(self): + for hour in self: + remaining_hour = 0.0 + for line in hour.planned_works: + remaining_hour += line.time_spent + self.remaining_hour = remaining_hour - self.effective_hour + + def process_demo_scheduler_queue(self): + obj = self.env['car.workshop'] + obj1 = obj.search([]) + now = fields.Datetime.from_string(fields.Datetime.now()) + for obj2 in obj1: + obj3 = obj2 + if obj3.stage_id.name != 'Done' and obj3.stage_id.name != 'Cancelled' and obj3.stage_id.name != 'Verified': + end_date = fields.Datetime.from_string(obj3.date_deadline) + start_date = fields.Datetime.from_string(obj3.date_assign) + if obj3.date_deadline and obj3.date_assign and end_date > start_date: + if now < end_date: + diff1 = relativedelta(end_date, start_date) + if diff1.days == 0: + total_hr = int(diff1.minutes) + else: + total_hr = int(diff1.days) * 24 * 60 + int(diff1.minutes) + diff2 = relativedelta(now, start_date) + if diff2.days == 0: + current_hr = int(diff2.minutes) + else: + current_hr = int(diff2.days) * 24 * 60 + int(diff2.minutes) + + if total_hr != 0: + obj3.progress = ((current_hr * 100) / total_hr) + else: + obj3.progress = 100 + else: + obj3.progress = 100 + else: + obj3.progress = 0 + + @api.model + def _track_subtype(self, init_values): + record = self.ensure_one() + if 'kanban_state' in init_values and record.kanban_state == 'blocked': + return self.env.ref('fleet_car_workshop.mt_task_blocked') + elif 'kanban_state' in init_values and record.kanban_state == 'done': + return self.env.ref('fleet_car_workshop.mt_task_ready') + elif 'user_id' in init_values and record.user_id: # assigned -> new + return self.env.ref('fleet_car_workshop.mt_task_new') + elif 'stage_id' in init_values and record.stage_id and record.stage_id.sequence <= 1: # start stage -> new + self.env.ref('fleet_car_workshop.mt_task_new') + elif 'stage_id' in init_values: + return self.env.ref('fleet_car_workshop.mt_task_stages') + return super(CarWorkshop, self)._track_subtype(init_values) + + @api.model + def create(self, vals): + # context: no_log, because subtype already handle this + context = dict(self.env.context, mail_create_nolog=True) + + # for default stage + if vals.get('vehicle_id') and not context.get('default_vehicle_id'): + context['default_vehicle_id'] = vals.get('vehicle_id') + # user_id change: update date_assign + if vals.get('user_id'): + vals['date_assign'] = fields.Datetime.now() + # Stage change: Update date_end if folded stage and date_last_stage_update + if vals.get('stage_id'): + vals.update(self.change_date_end(vals['stage_id'])) + vals['date_last_stage_update'] = fields.Datetime.now() + task = super(CarWorkshop, self.with_context(context)).create(vals) + return task + + def write(self, vals): + now = fields.Datetime.now(self) + # stage change: update date_last_stage_update + if 'stage_id' in vals: + vals.update(self.change_date_end(vals['stage_id'])) + vals['date_last_stage_update'] = now + # reset kanban state when changing stage + if 'kanban_state' not in vals: + vals['kanban_state'] = 'normal' + # user_id change: update date_assign + if vals.get('user_id') and 'date_assign' not in vals: + vals['date_assign'] = now + result = super(CarWorkshop, self).write(vals) + return result + + def change_date_end(self, stage_id): + worksheet_stage = self.env['worksheet.stages'].browse(stage_id) + if worksheet_stage.fold: + return {'date_end': fields.Datetime.now()} + return {'date_end': False} + + @api.onchange('vehicle_id') + def onchange_vehicle(self): + # values = {} + if self.vehicle_id.exists(): + # vehicle = self.pool.get('fleet.vehicle').browse(cr, uid, vehicle_id, context=context) + # if self.vehicle_id.exists():` + self.partner_id = self.vehicle_id.partner_id + self.stage_id = self.stage_find(self.vehicle_id, [('fold', '=', False)]) + + + def stage_find(self, section_id, domain=[], order='sequence'): + """ Override of the base.stage method + Parameter of the stage search taken from the lead: + - section_id: if set, stages must belong to this section or + be a default stage; if not set, stages must be default + stages + """ + # collect all section_ids + section_ids = [] + if section_id: + section_ids.append(section_id) + section_ids.extend(self.mapped('vehicle_id').ids) + search_domain = [] + if section_ids: + search_domain = [('|')] * (len(section_ids) - 1) + for section_id in section_ids: + if isinstance(section_id, (int, long)): + search_domain.append(('vehicle_ids', '=', section_id)) + search_domain += list(domain) + # perform search, return the first found + stage_ids = self.env['worksheet.stages'].search(search_domain, order=order, limit=1).id + if stage_ids: + return stage_ids + return False + + def get_invoices(self): + self.ensure_one() + return { + 'type': 'ir.actions.act_window', + 'name': 'Invoices', + 'view_mode': 'tree,form', + 'view_type': 'form', + 'res_model': 'account.move', + 'domain': [('invoice_origin', '=', self.name)], + 'context': "{'create': False}" + } + + def compute_invoice_count(self): + print(self.env['account.move'].search([]),'self') + for record in self: + record.invoice_count = self.env['account.move'].search_count( + [('invoice_origin', '=', self.name)]) \ No newline at end of file diff --git a/fleet_car_workshop/models/config.py b/fleet_car_workshop/models/config.py new file mode 100644 index 000000000..dbf057732 --- /dev/null +++ b/fleet_car_workshop/models/config.py @@ -0,0 +1,61 @@ +# -*- coding: utf-8 -*- +############################################################################## +# +# Cybrosys Technologies Pvt. Ltd. +# Copyright (C) 2022-TODAY Cybrosys Technologies(). +# Author: ASWATHI C () +# you can modify it under the terms of the GNU LESSER +# GENERAL PUBLIC LICENSE (LGPL 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 LESSER GENERAL PUBLIC LICENSE (LGPL v3) for more details. +# +# You should have received a copy of the GNU LESSER GENERAL PUBLIC LICENSE +# GENERAL PUBLIC LICENSE (LGPL v3) along with this program. +# If not, see . +# +############################################################################## +from odoo.tools.translate import _ +from odoo import fields, models, api + + +from odoo import fields, models + + +class WorkshopSetting(models.TransientModel): + _inherit = 'res.config.settings' + + invoice_journal_type = fields.Many2one('account.journal', string="Car Workshop Journal", config_parameter='fleet_car_workshop.invoice_journal_type') + + +class WorksheetTags(models.Model): + _name = "worksheet.tags" + _description = "Tags of vehicles's tasks, issues..." + + name = fields.Char('Name', required=True) + color = fields.Integer('Color Index') + + _sql_constraints = [ + ('name_uniq', 'unique (name)', "Tag name already exists !"), + ] + + +class WorksheetStages(models.Model): + _name = 'worksheet.stages' + _description = 'worksheet Stage' + _order = 'sequence' + + def _get_default_vehicle_ids(self): + default_vehicle_id = self.env.context.get('default_vehicle_id') + return [default_vehicle_id] if default_vehicle_id else None + + name = fields.Char(string='Stage Name', required=True) + description = fields.Text(string='Description', translate=True) + sequence = fields.Integer(string='Sequence') + vehicle_ids = fields.Many2many('car.car', 'worksheet_type_rel', 'type_id', 'vehicle_id', string='Vechicles', + default=_get_default_vehicle_ids) + fold = fields.Boolean('Folded in Tasks Pipeline', + help='This stage is folded in the kanban view when ' + 'there are no records in that stage to display.') diff --git a/fleet_car_workshop/models/dashboard.py b/fleet_car_workshop/models/dashboard.py new file mode 100644 index 000000000..d256bd1ca --- /dev/null +++ b/fleet_car_workshop/models/dashboard.py @@ -0,0 +1,109 @@ +# -*- coding: utf-8 -*- +############################################################################## +# +# Cybrosys Technologies Pvt. Ltd. +# Copyright (C) 2022-TODAY Cybrosys Technologies(). +# Author: ASWATHI C () +# you can modify it under the terms of the GNU LESSER +# GENERAL PUBLIC LICENSE (LGPL 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 LESSER GENERAL PUBLIC LICENSE (LGPL v3) for more details. +# +# You should have received a copy of the GNU LESSER GENERAL PUBLIC LICENSE +# GENERAL PUBLIC LICENSE (LGPL v3) along with this program. +# If not, see . +# +############################################################################## +import base64 + +from odoo.osv import osv +from odoo.tools.translate import _ +from odoo import fields, api + + +class CarVehicle(osv.osv): + _name = 'car.car' + _description = "Vechicles" + _inherit = ['mail.thread'] + _rec_name = 'vehicle_id' + + + active = fields.Boolean('Active',default=True) + vehicle_id = fields.Many2one('fleet.vehicle', string='Vehicle Name', tracking=True, required=True) + sequence = fields.Integer('Sequence', help="Gives the sequence order when displaying a list of Projects.") + + label_tasks = fields.Char(string='Use Tasks as', help="Gives label to Work on kanban view.", default="Task") + worksheet = fields.One2many('car.workshop', 'vehicle_id', string="Task Activities") + + type_ids = fields.Many2many('worksheet.stages', 'car_workshop_type_rel', + 'vehicle_id', 'type_id', string='Worksheet Stages', + states={'close': [('readonly', True)], 'cancelled': [('readonly', True)]}) + + task_count = fields.Integer(compute='_compute_task_count', type='integer', string="Tasks" ) + task_ids = fields.One2many('car.workshop', 'vehicle_id', domain=['|', ('stage_id.fold', '=', False), ('stage_id', '=', False)]) + doc_count = fields.Integer(compute='_compute_attached_docs_count', string="Number of documents attached") + color = fields.Integer(string='Color Index') + partner_id = fields.Many2one('res.partner', string='Customer') + state = fields.Selection([('draft', 'New'), + ('open', 'In Progress'), + ('cancelled', 'Cancelled'), + ('pending', 'Pending'), + ('close', 'Closed')], string='Status', required=True, + track_visibility='onchange',default='open', copy=False) + + date_start = fields.Date(string='Start Date') + date = fields.Date(string='Expiration Date', select=True, track_visibility='onchange') + use_tasks = fields.Boolean(string='Tasks', default=True) + image_128 = fields.Image(related='vehicle_id.image_128', readonly=False) + + def _get_visibility_selection_id(self, cr, uid, context=None): + return [('portal', _('Customer Works: visible in portal if the customer is a follower')), + ('employees', _('All Employees Work: all employees can access')), + ('followers', _('Private Work: followers only'))] + + _visibility_selections = lambda self, *args, **kwargs: self._get_visibility_selection_id(*args, **kwargs) + + def _compute_attached_docs_count(self): + Attachment = self.env['ir.attachment'] + for vehicle in self: + vehicle.doc_count = Attachment.search_count([ + '|', + '&', + ('res_model', '=', 'car.car'), ('res_id', '=', vehicle.id), + '&', + ('res_model', '=', 'car.worksheet'), ('res_id', 'in', vehicle.task_ids.ids) + ]) + + def _compute_task_count(self): + for vehicle in self: + vehicle.task_count = len(vehicle.task_ids) + + def attachment_tree_views(self): + self.ensure_one() + domain = [ + '|', + '&', ('res_model', '=', 'car.car'), ('res_id', 'in', self.ids), + '&', ('res_model', '=', 'car.workshop'), ('res_id', 'in', self.task_ids.ids)] + + return { + 'name': _('Attachments'), + 'domain': domain, + 'res_model': 'ir.attachment', + 'type': 'ir.actions.act_window', + 'view_id': False, + 'view_mode': 'kanban,tree,form', + 'view_type': 'form', + 'help': _('''

+ Documents are attached to the tasks and issues of your Worksheet.

+ Send messages or log internal notes with attachments to link + documents to your Worksheet. +

'''), + 'limit': 80, + 'context': "{'default_res_model': '%s','default_res_id': %d}" % (self._name, self.id) + } + + + diff --git a/fleet_car_workshop/models/timesheet.py b/fleet_car_workshop/models/timesheet.py new file mode 100644 index 000000000..367a9ce7b --- /dev/null +++ b/fleet_car_workshop/models/timesheet.py @@ -0,0 +1,54 @@ +# -*- coding: utf-8 -*- +############################################################################## +# +# Cybrosys Technologies Pvt. Ltd. +# Copyright (C) 2022-TODAY Cybrosys Technologies(). +# Author: ASWATHI C () +# you can modify it under the terms of the GNU LESSER +# GENERAL PUBLIC LICENSE (LGPL 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 LESSER GENERAL PUBLIC LICENSE (LGPL v3) for more details. +# +# You should have received a copy of the GNU LESSER GENERAL PUBLIC LICENSE +# GENERAL PUBLIC LICENSE (LGPL v3) along with this program. +# If not, see . +# +############################################################################## + +from odoo import fields, models, api + + +class PlannedWork (models.Model): + _name = 'planned.work' + + planned_work = fields.Many2one('product.product', string='Planned work', domain=[('type', '=', 'service')]) + time_spent = fields.Float(string='Estimated Time') + work_date = fields.Datetime(string='Date') # Date of work planned:planned date + responsible = fields.Many2one('res.users', string='Responsible') + work_id = fields.Many2one('car.workshop', string="Work id") + work_cost = fields.Float(string="Service Cost") + completed = fields.Boolean(string="Completed") + duration = fields.Float(string='Duration') + work_date2 = fields.Datetime(string='Date') # Date of work completed/done:completed date + + @api.onchange('planned_work') + def get_price(self): + self.work_cost = self.planned_work.lst_price + + +class MaterialUsed (models.Model): + _name = 'material.used' + + material = fields.Many2one('product.product', string='Products') + amount = fields.Integer(string='Quantity') + price = fields.Float(string='Unit Price') + material_id = fields.Many2one('car.workshop') + _defaults = { + 'amount': 1, } + + @api.onchange('material') + def get_price(self): + self.price = self.material.lst_price diff --git a/fleet_car_workshop/security/ir.model.access.csv b/fleet_car_workshop/security/ir.model.access.csv new file mode 100644 index 000000000..1e88b0943 --- /dev/null +++ b/fleet_car_workshop/security/ir.model.access.csv @@ -0,0 +1,15 @@ +id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink + +access_car_car_user,car.car.user,fleet_car_workshop.model_car_car,fleet.fleet_group_user,1,0,0,0 +access_car_workshop_user,car.workshop.user,fleet_car_workshop.model_car_workshop,fleet.fleet_group_user,1,0,0,0 +access_worksheet_tags_all_user,car.car_tags_all,fleet_car_workshop.model_worksheet_tags,fleet.fleet_group_user,1,0,0,0 +access_worksheet_stages_user,worksheet.stages.user,fleet_car_workshop.model_worksheet_stages,fleet.fleet_group_user,1,0,0,0 +access_material_used_user,material.used.user,fleet_car_workshop.model_material_used,fleet.fleet_group_user,1,0,0,0 +access_planned_work_user,planned.work.user,fleet_car_workshop.model_planned_work,fleet.fleet_group_user,1,0,0,0 + +access_car_car_manager,car.car.manager,fleet_car_workshop.model_car_car,fleet.fleet_group_manager,1,1,1,1 +access_car_workshop_manager,car.workshop.manager,fleet_car_workshop.model_car_workshop,fleet.fleet_group_manager,1,1,1,1 +access_worksheet_tags_all_manager,car.car_tags_all.manager,fleet_car_workshop.model_worksheet_tags,fleet.fleet_group_manager,1,1,1,1 +access_worksheet_stages_manager,worksheet.stages.manager,fleet_car_workshop.model_worksheet_stages,fleet.fleet_group_manager,1,1,1,1 +access_material_used_manager,material.used.manager,fleet_car_workshop.model_material_used,fleet.fleet_group_manager,1,1,1,1 +access_planned_work_manager,planned.work.manager,fleet_car_workshop.model_planned_work,fleet.fleet_group_manager,1,1,1,1 \ No newline at end of file diff --git a/fleet_car_workshop/security/workshop_security.xml b/fleet_car_workshop/security/workshop_security.xml new file mode 100644 index 000000000..961bc0884 --- /dev/null +++ b/fleet_car_workshop/security/workshop_security.xml @@ -0,0 +1,25 @@ + + + + + + + + + + + + + + + + + + + + Manager has all rights on vehicle + + + + + diff --git a/fleet_car_workshop/static/10.png b/fleet_car_workshop/static/10.png new file mode 100644 index 000000000..c986ee53b Binary files /dev/null and b/fleet_car_workshop/static/10.png differ diff --git a/fleet_car_workshop/static/description/assets/icons/check.png b/fleet_car_workshop/static/description/assets/icons/check.png new file mode 100644 index 000000000..c8e85f51d Binary files /dev/null and b/fleet_car_workshop/static/description/assets/icons/check.png differ diff --git a/fleet_car_workshop/static/description/assets/icons/chevron.png b/fleet_car_workshop/static/description/assets/icons/chevron.png new file mode 100644 index 000000000..2089293d6 Binary files /dev/null and b/fleet_car_workshop/static/description/assets/icons/chevron.png differ diff --git a/fleet_car_workshop/static/description/assets/icons/cogs.png b/fleet_car_workshop/static/description/assets/icons/cogs.png new file mode 100644 index 000000000..95d0bad62 Binary files /dev/null and b/fleet_car_workshop/static/description/assets/icons/cogs.png differ diff --git a/fleet_car_workshop/static/description/assets/icons/consultation.png b/fleet_car_workshop/static/description/assets/icons/consultation.png new file mode 100644 index 000000000..8319d4baa Binary files /dev/null and b/fleet_car_workshop/static/description/assets/icons/consultation.png differ diff --git a/fleet_car_workshop/static/description/assets/icons/ecom-black.png b/fleet_car_workshop/static/description/assets/icons/ecom-black.png new file mode 100644 index 000000000..a9385ff13 Binary files /dev/null and b/fleet_car_workshop/static/description/assets/icons/ecom-black.png differ diff --git a/fleet_car_workshop/static/description/assets/icons/education-black.png b/fleet_car_workshop/static/description/assets/icons/education-black.png new file mode 100644 index 000000000..3eb09b27b Binary files /dev/null and b/fleet_car_workshop/static/description/assets/icons/education-black.png differ diff --git a/fleet_car_workshop/static/description/assets/icons/hotel-black.png b/fleet_car_workshop/static/description/assets/icons/hotel-black.png new file mode 100644 index 000000000..130f613be Binary files /dev/null and b/fleet_car_workshop/static/description/assets/icons/hotel-black.png differ diff --git a/fleet_car_workshop/static/description/assets/icons/license.png b/fleet_car_workshop/static/description/assets/icons/license.png new file mode 100644 index 000000000..a5869797e Binary files /dev/null and b/fleet_car_workshop/static/description/assets/icons/license.png differ diff --git a/fleet_car_workshop/static/description/assets/icons/lifebuoy.png b/fleet_car_workshop/static/description/assets/icons/lifebuoy.png new file mode 100644 index 000000000..658d56ccc Binary files /dev/null and b/fleet_car_workshop/static/description/assets/icons/lifebuoy.png differ diff --git a/fleet_car_workshop/static/description/assets/icons/manufacturing-black.png b/fleet_car_workshop/static/description/assets/icons/manufacturing-black.png new file mode 100644 index 000000000..697eb0e9f Binary files /dev/null and b/fleet_car_workshop/static/description/assets/icons/manufacturing-black.png differ diff --git a/fleet_car_workshop/static/description/assets/icons/pos-black.png b/fleet_car_workshop/static/description/assets/icons/pos-black.png new file mode 100644 index 000000000..97c0f90c1 Binary files /dev/null and b/fleet_car_workshop/static/description/assets/icons/pos-black.png differ diff --git a/fleet_car_workshop/static/description/assets/icons/puzzle.png b/fleet_car_workshop/static/description/assets/icons/puzzle.png new file mode 100644 index 000000000..65cf854e7 Binary files /dev/null and b/fleet_car_workshop/static/description/assets/icons/puzzle.png differ diff --git a/fleet_car_workshop/static/description/assets/icons/restaurant-black.png b/fleet_car_workshop/static/description/assets/icons/restaurant-black.png new file mode 100644 index 000000000..4a35eb939 Binary files /dev/null and b/fleet_car_workshop/static/description/assets/icons/restaurant-black.png differ diff --git a/fleet_car_workshop/static/description/assets/icons/service-black.png b/fleet_car_workshop/static/description/assets/icons/service-black.png new file mode 100644 index 000000000..301ab51cb Binary files /dev/null and b/fleet_car_workshop/static/description/assets/icons/service-black.png differ diff --git a/fleet_car_workshop/static/description/assets/icons/trading-black.png b/fleet_car_workshop/static/description/assets/icons/trading-black.png new file mode 100644 index 000000000..9398ba2f1 Binary files /dev/null and b/fleet_car_workshop/static/description/assets/icons/trading-black.png differ diff --git a/fleet_car_workshop/static/description/assets/icons/training.png b/fleet_car_workshop/static/description/assets/icons/training.png new file mode 100644 index 000000000..884ca024d Binary files /dev/null and b/fleet_car_workshop/static/description/assets/icons/training.png differ diff --git a/fleet_car_workshop/static/description/assets/icons/update.png b/fleet_car_workshop/static/description/assets/icons/update.png new file mode 100644 index 000000000..ecbc5a01a Binary files /dev/null and b/fleet_car_workshop/static/description/assets/icons/update.png differ diff --git a/fleet_car_workshop/static/description/assets/icons/user.png b/fleet_car_workshop/static/description/assets/icons/user.png new file mode 100644 index 000000000..6ffb23d9f Binary files /dev/null and b/fleet_car_workshop/static/description/assets/icons/user.png differ diff --git a/fleet_car_workshop/static/description/assets/icons/wrench.png b/fleet_car_workshop/static/description/assets/icons/wrench.png new file mode 100644 index 000000000..6c04dea0f Binary files /dev/null and b/fleet_car_workshop/static/description/assets/icons/wrench.png differ diff --git a/fleet_car_workshop/static/description/assets/misc/categories.png b/fleet_car_workshop/static/description/assets/misc/categories.png new file mode 100644 index 000000000..bedf1e0b1 Binary files /dev/null and b/fleet_car_workshop/static/description/assets/misc/categories.png differ diff --git a/fleet_car_workshop/static/description/assets/misc/check-box.png b/fleet_car_workshop/static/description/assets/misc/check-box.png new file mode 100644 index 000000000..42caf24b9 Binary files /dev/null and b/fleet_car_workshop/static/description/assets/misc/check-box.png differ diff --git a/fleet_car_workshop/static/description/assets/misc/compass.png b/fleet_car_workshop/static/description/assets/misc/compass.png new file mode 100644 index 000000000..d5fed8faa Binary files /dev/null and b/fleet_car_workshop/static/description/assets/misc/compass.png differ diff --git a/fleet_car_workshop/static/description/assets/misc/corporate.png b/fleet_car_workshop/static/description/assets/misc/corporate.png new file mode 100644 index 000000000..2eb13edbf Binary files /dev/null and b/fleet_car_workshop/static/description/assets/misc/corporate.png differ diff --git a/fleet_car_workshop/static/description/assets/misc/customer-support.png b/fleet_car_workshop/static/description/assets/misc/customer-support.png new file mode 100644 index 000000000..79efc72ed Binary files /dev/null and b/fleet_car_workshop/static/description/assets/misc/customer-support.png differ diff --git a/fleet_car_workshop/static/description/assets/misc/cybrosys-logo.png b/fleet_car_workshop/static/description/assets/misc/cybrosys-logo.png new file mode 100644 index 000000000..cc3cc0ccf Binary files /dev/null and b/fleet_car_workshop/static/description/assets/misc/cybrosys-logo.png differ diff --git a/fleet_car_workshop/static/description/assets/misc/features.png b/fleet_car_workshop/static/description/assets/misc/features.png new file mode 100644 index 000000000..b41769f77 Binary files /dev/null and b/fleet_car_workshop/static/description/assets/misc/features.png differ diff --git a/fleet_car_workshop/static/description/assets/misc/logo.png b/fleet_car_workshop/static/description/assets/misc/logo.png new file mode 100644 index 000000000..478462d3e Binary files /dev/null and b/fleet_car_workshop/static/description/assets/misc/logo.png differ diff --git a/fleet_car_workshop/static/description/assets/misc/pictures.png b/fleet_car_workshop/static/description/assets/misc/pictures.png new file mode 100644 index 000000000..56d255fe9 Binary files /dev/null and b/fleet_car_workshop/static/description/assets/misc/pictures.png differ diff --git a/fleet_car_workshop/static/description/assets/misc/pie-chart.png b/fleet_car_workshop/static/description/assets/misc/pie-chart.png new file mode 100644 index 000000000..426e05244 Binary files /dev/null and b/fleet_car_workshop/static/description/assets/misc/pie-chart.png differ diff --git a/fleet_car_workshop/static/description/assets/misc/right-arrow.png b/fleet_car_workshop/static/description/assets/misc/right-arrow.png new file mode 100644 index 000000000..730984a06 Binary files /dev/null and b/fleet_car_workshop/static/description/assets/misc/right-arrow.png differ diff --git a/fleet_car_workshop/static/description/assets/misc/star.png b/fleet_car_workshop/static/description/assets/misc/star.png new file mode 100644 index 000000000..2eb9ab29f Binary files /dev/null and b/fleet_car_workshop/static/description/assets/misc/star.png differ diff --git a/fleet_car_workshop/static/description/assets/misc/support.png b/fleet_car_workshop/static/description/assets/misc/support.png new file mode 100644 index 000000000..4f18b8b82 Binary files /dev/null and b/fleet_car_workshop/static/description/assets/misc/support.png differ diff --git a/fleet_car_workshop/static/description/assets/misc/whatsapp.png b/fleet_car_workshop/static/description/assets/misc/whatsapp.png new file mode 100644 index 000000000..d513a5356 Binary files /dev/null and b/fleet_car_workshop/static/description/assets/misc/whatsapp.png differ diff --git a/fleet_car_workshop/static/description/assets/modules/1.png b/fleet_car_workshop/static/description/assets/modules/1.png new file mode 100644 index 000000000..5238bdeab Binary files /dev/null and b/fleet_car_workshop/static/description/assets/modules/1.png differ diff --git a/fleet_car_workshop/static/description/assets/modules/2.png b/fleet_car_workshop/static/description/assets/modules/2.png new file mode 100644 index 000000000..1ae7cfe3b Binary files /dev/null and b/fleet_car_workshop/static/description/assets/modules/2.png differ diff --git a/fleet_car_workshop/static/description/assets/modules/3.png b/fleet_car_workshop/static/description/assets/modules/3.png new file mode 100644 index 000000000..3c3ff1afb Binary files /dev/null and b/fleet_car_workshop/static/description/assets/modules/3.png differ diff --git a/fleet_car_workshop/static/description/assets/modules/4.png b/fleet_car_workshop/static/description/assets/modules/4.png new file mode 100644 index 000000000..3fae4631e Binary files /dev/null and b/fleet_car_workshop/static/description/assets/modules/4.png differ diff --git a/fleet_car_workshop/static/description/assets/modules/5.gif b/fleet_car_workshop/static/description/assets/modules/5.gif new file mode 100644 index 000000000..2a5f8e659 Binary files /dev/null and b/fleet_car_workshop/static/description/assets/modules/5.gif differ diff --git a/fleet_car_workshop/static/description/assets/modules/6.png b/fleet_car_workshop/static/description/assets/modules/6.png new file mode 100644 index 000000000..7f2815273 Binary files /dev/null and b/fleet_car_workshop/static/description/assets/modules/6.png differ diff --git a/fleet_car_workshop/static/description/assets/screenshots/1.1.png b/fleet_car_workshop/static/description/assets/screenshots/1.1.png new file mode 100644 index 000000000..106f74649 Binary files /dev/null and b/fleet_car_workshop/static/description/assets/screenshots/1.1.png differ diff --git a/fleet_car_workshop/static/description/assets/screenshots/1.2.png b/fleet_car_workshop/static/description/assets/screenshots/1.2.png new file mode 100644 index 000000000..bf54304eb Binary files /dev/null and b/fleet_car_workshop/static/description/assets/screenshots/1.2.png differ diff --git a/fleet_car_workshop/static/description/assets/screenshots/1.3.png b/fleet_car_workshop/static/description/assets/screenshots/1.3.png new file mode 100644 index 000000000..ec6f369db Binary files /dev/null and b/fleet_car_workshop/static/description/assets/screenshots/1.3.png differ diff --git a/fleet_car_workshop/static/description/assets/screenshots/1.4.png b/fleet_car_workshop/static/description/assets/screenshots/1.4.png new file mode 100644 index 000000000..4767f9dfc Binary files /dev/null and b/fleet_car_workshop/static/description/assets/screenshots/1.4.png differ diff --git a/fleet_car_workshop/static/description/assets/screenshots/1.5.png b/fleet_car_workshop/static/description/assets/screenshots/1.5.png new file mode 100644 index 000000000..eb3b07ec8 Binary files /dev/null and b/fleet_car_workshop/static/description/assets/screenshots/1.5.png differ diff --git a/fleet_car_workshop/static/description/assets/screenshots/1.7.png b/fleet_car_workshop/static/description/assets/screenshots/1.7.png new file mode 100644 index 000000000..7ee84f02e Binary files /dev/null and b/fleet_car_workshop/static/description/assets/screenshots/1.7.png differ diff --git a/fleet_car_workshop/static/description/assets/screenshots/1.8.png b/fleet_car_workshop/static/description/assets/screenshots/1.8.png new file mode 100644 index 000000000..65e110c72 Binary files /dev/null and b/fleet_car_workshop/static/description/assets/screenshots/1.8.png differ diff --git a/fleet_car_workshop/static/description/assets/screenshots/1.9.png b/fleet_car_workshop/static/description/assets/screenshots/1.9.png new file mode 100644 index 000000000..d503efce9 Binary files /dev/null and b/fleet_car_workshop/static/description/assets/screenshots/1.9.png differ diff --git a/fleet_car_workshop/static/description/assets/screenshots/hero.gif b/fleet_car_workshop/static/description/assets/screenshots/hero.gif new file mode 100644 index 000000000..6da356080 Binary files /dev/null and b/fleet_car_workshop/static/description/assets/screenshots/hero.gif differ diff --git a/fleet_car_workshop/static/description/banner.png b/fleet_car_workshop/static/description/banner.png new file mode 100644 index 000000000..f9706edbe Binary files /dev/null and b/fleet_car_workshop/static/description/banner.png differ diff --git a/fleet_car_workshop/static/description/icon.png b/fleet_car_workshop/static/description/icon.png new file mode 100644 index 000000000..844d66d35 Binary files /dev/null and b/fleet_car_workshop/static/description/icon.png differ diff --git a/fleet_car_workshop/static/description/index.html b/fleet_car_workshop/static/description/index.html new file mode 100644 index 000000000..ee1aab5c8 --- /dev/null +++ b/fleet_car_workshop/static/description/index.html @@ -0,0 +1,588 @@ +
+ +
+ +
+
+ Community +
+
+ Enterprise +
+
+ Odoo.sh +
+
+
+ +
+
+
+ +

+ Car Workshop Management

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

Explore This + Module

+
+ + + + +
+
+ +
+

Overview +

+
+
+
+ Car Workshop Management is a Cybrosys Generic Module to manage automobile workshop with + great ease. Keep track of everything, like vehicle owner details, + Works assigned, Bill details of service provided,etc.. +
+
+ + + +
+
+ +
+

Features +

+
+
+
+
+ + User Friendly Interface. +
+
+ + Effective Time management. +
+
+ + Separate Journal Configuration. +
+
+ + Integrated with Accounting. +
+
+
+ +
+ + High Scalability. +
+
+
+ + + +
+
+ +
+

Screenshots +

+
+
+
+ +
+

Dashboard/All Vehicles +

+

Whole Workshop Analysis

+ +
+ +
+

All works +

+

Goto Car Workshop -->Worksheet + Organise all the works according to their Status. Works/Tasks assigned works using the kanban view and control deadlines in the calendar view.Each Work may have it's own stages.

+

Kanban

+ +
+
+

Calendar +

+ +
+
+

Worksheet View +

+

All details related to a work/task

+ +
+
+

Timesheet +

+

Goto Car Workshop >Worksheet >Timesheet + In timesheet ,Planned work is the sub works related to main Work. By ticking 'Completed' that work will be automatically updated to Work done.
+ + Work done is the details of completed works.
+ + Hour spent is time taken for completed work(Work Done).
+ + Remaining Hour is total time left(Difference between Total Time and Hour Spent).

+ +
+
+

Report +

+

Tabular Details of Vehicles

+ +
+
+

Settings +

+

Configure Preferred journal for Invoicing + Goto Car Workshop >Configuration >Settings

+ +
+
+

Separate Journal +

+

Invoices from the car workshop will be saved to Separate journal. + Goto Car Workshop >Worksheet >Create Invoices

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

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/fleet_car_workshop/static/src/css/vehicles.css b/fleet_car_workshop/static/src/css/vehicles.css new file mode 100644 index 000000000..c6e6d31c5 --- /dev/null +++ b/fleet_car_workshop/static/src/css/vehicles.css @@ -0,0 +1,40 @@ + +.oe_kanban_project_avatars img { + width: 30px; + border-radius: 2px; + -moz-box-shadow: 0 1px 2px rgba(0, 0, 0, 0.2); + -webkit-box-shadow: 0 1px 2px rgba(0, 0, 0, 0.2); + -box-shadow: 0 1px 2px rgba(0, 0, 0, 0.2); +} +.oe_form_gantt_avatars:after { + font-family: "mnmliconsRegular" !important; + font-size: 21px; + font-weight: 300 !important; + content: "y"; + top: 3px; + position: relative; +} + +.openerp .oe_kanban_view .oe_kanban_project { + width: 250px; + min-height: 160px !important; + cursor: default; +} + +.openerp .oe_percent strong:after { + content: "%"; +} + +.openerp .oe_margin_top_8 { + margin-top: 8px; +} +.openerp .oe_kanban_project .oe_kanban_project_list .col-md-6 a{ + margin-left: 5px; +} + +/* Kanban status as label in project stage form view */ +.openerp label.oe_project_kanban_legend { + min-width: inherit !important; + margin-top: 6px; + margin-right: 8px; +} diff --git a/fleet_car_workshop/static/src/less/car_dashboard.less b/fleet_car_workshop/static/src/less/car_dashboard.less new file mode 100644 index 000000000..bc800a569 --- /dev/null +++ b/fleet_car_workshop/static/src/less/car_dashboard.less @@ -0,0 +1,38 @@ +.o_kanban_view.o_kanban_dashboard.o_project_kanban { + .o_project_kanban_boxes { + display: flex; + flex-flow: row wrap; + justify-content: space-between; + + .o_project_kanban_box { + position: relative; + text-align: center; + padding: 0 0 0 0; + margin: 0 5px; + + .o_value { + font-weight: 800; + } + + > div { + font-weight: 500; + + button.o_needaction { + font-size: small; + font-weight: 400; + margin-left: 4px; + @include o-hover-opacity(0.5, 1); + + &:before { + content: "/ "; + } + + &:after { + content: "\f086"; + font: normal normal normal 14px/1 FontAwesome; + } + } + } + } + } +} \ No newline at end of file diff --git a/fleet_car_workshop/views/car_dashboard.xml b/fleet_car_workshop/views/car_dashboard.xml new file mode 100644 index 000000000..fae5a14cf --- /dev/null +++ b/fleet_car_workshop/views/car_dashboard.xml @@ -0,0 +1,215 @@ + + + car.car.form + car.car + +
+
+ +
+ +
+ + + + + +
+ +
+

+ +

+
+
+ +
+
+
+ + + + + + + + +
+
+ + +
+
+
+
+ + + car.car.select + car.car + + + + + + + + + + + + + + + + + + car.car.kanban + car.car + + + + + + + + + + + + + +
+
+
+
+ Vehicle +
+
+
+
+ + + +
+
+ +
+
+
+ + +
+
+ + + +
+
+ + +
+
+
+
+
+
+ + + car.car.tree + car.car + child_ids + + + + + + + + + + + Vehicles + car.car + + [] + kanban,form + + {'search_default_Current': 1} + +

+ Create a new project. +

+

+ Organize your activities (plan tasks, track issues, invoice timesheets) for internal, personal or + customer projects. +

+
+
+ + + Vehicles + car.car + + [] + tree,form + + {'search_default_Current': 1} + +

+ Create a new vehicle. +

+
+
+ + + +
\ No newline at end of file diff --git a/fleet_car_workshop/views/configuration_settings_view.xml b/fleet_car_workshop/views/configuration_settings_view.xml new file mode 100644 index 000000000..050fa3f8b --- /dev/null +++ b/fleet_car_workshop/views/configuration_settings_view.xml @@ -0,0 +1,41 @@ + + + + Settings + ir.actions.act_window + res.config.settings + form + inline + {'module' : 'fleet_car_workshop'} + + + + res wrk shop settings + res.config.settings + + + + +
+

Car Work Shop

+
+
+
+
+ Seperate Journal +
+ Choose Journal + +
+
+
+
+
+ + + + + + \ No newline at end of file diff --git a/fleet_car_workshop/views/report.xml b/fleet_car_workshop/views/report.xml new file mode 100644 index 000000000..6d2e5c96e --- /dev/null +++ b/fleet_car_workshop/views/report.xml @@ -0,0 +1,15 @@ + + + Worksheets + car.workshop + pivot,graph + +

+ Odoo's car workshop management allows you to manage the pipeline of your work efficiently. You can track + progress, discuss on works, attach documents, etc. +

+
+
+ + +
\ No newline at end of file diff --git a/fleet_car_workshop/views/timesheet_view.xml b/fleet_car_workshop/views/timesheet_view.xml new file mode 100644 index 000000000..5d33c2c5e --- /dev/null +++ b/fleet_car_workshop/views/timesheet_view.xml @@ -0,0 +1,53 @@ + + + + planned.work.form + planned.work + +
+ + + + + + + + + + + +
+
+
+ + + material.used.form + material.used + +
+ + + + + + + + + +
+
+
+ + + material.used.tree + material.used + + + + + + + + +
+
\ No newline at end of file diff --git a/fleet_car_workshop/views/worksheet_stages.xml b/fleet_car_workshop/views/worksheet_stages.xml new file mode 100644 index 000000000..ab2ae078a --- /dev/null +++ b/fleet_car_workshop/views/worksheet_stages.xml @@ -0,0 +1,124 @@ + + + + worksheet.stages.form + worksheet.stages + +
+ +
+
+
+

+ +

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

+ You can also add a description to help your co-workers understand the meaning and + purpose of the stage. +

+ +
+
+
+
+
+ + + worksheet.stages.tree + worksheet.stages + + + + + + + + + + + + + Stages + worksheet.stages + tree,form + + + + Tags + worksheet.tags + + + + + + + + + + + Tags + worksheet.tags + +
+ + + + + + + + + + + +
+
+
+ + + + Tags + worksheet.tags + tree,form + +

+ Click to add a new tag. +

+
+
+ + + + Service-Products + ir.actions.act_window + product.product + kanban,tree,form + {"search_default_services":'service'} + +

+ Click to define a new product. +

+
+
+ + + + +
+
diff --git a/fleet_car_workshop/views/worksheet_views.xml b/fleet_car_workshop/views/worksheet_views.xml new file mode 100644 index 000000000..0cd811e4d --- /dev/null +++ b/fleet_car_workshop/views/worksheet_views.xml @@ -0,0 +1,320 @@ + + + + Demo scheduler + + 1 + minutes + -1 + + + code + model.process_demo_scheduler_queue() + + + + worksheet.form.view + car.workshop + +
+
+
+
+ +
+ + +
+ +
+ +
+

+ + + +

+
+ + + + + + + + + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + +
+ + + + + + car workshop kanban + car.workshop + + + + + + + + + + + + + + + + + +
+ + + +
+
+ +
+
+ + + +
+
+ + oe_kanban_text_red + + + + + + +
+
+ + +
+
+ img +
+ +
+
+
+
+ +
+
+
+
+
+
+
+
+ + + + worksheet.tree.view + car.workshop + + + + + + + + + + + + + + + worksheet.calender.view + car.workshop + + + + + + + + + + + car.workshop.pivot + car.workshop + + + + + + + + + + car.workshop.graph + car.workshop + + + + + + + + + + car.workshop.search.form + car.workshop + + + + + + + + + + + + + + + + + + + + + + + + + + + + Worksheets + car.workshop + kanban,tree,form,calendar,pivot,graph + {'search_default_vehicle_id': [active_id], + 'default_vehicle_id':active_id} + + + +

+ Odoo's car workshop management allows you to manage the pipeline of your work efficiently. You can + track progress, discuss on works, attach documents, etc. +

+
+
+ + + + Worksheets + car.workshop + kanban,tree,form,calendar,pivot,graph + +

+ Odoo's car workshop management allows you to manage the pipeline of your work efficiently. You can + track progress, discuss on works, attach documents, etc. +

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