# -*- coding: utf-8 -*- ############################################################################## # # Cybrosys Technologies Pvt. Ltd. # Copyright (C) 2008-TODAY Cybrosys Technologies(). # Author: Nilmar Shereef() # you can modify it under the terms of the GNU LESSER # GENERAL PUBLIC LICENSE (LGPL v3), Version 3. # # It is forbidden to publish, distribute, sublicense, or sell copies # of the Software or modified copies of the Software. # # 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 from dateutil.relativedelta import relativedelta from openerp import models, api, fields, _ from openerp.osv import osv class CarWorkshop(models.Model): _name = 'car.workshop' _inherit = ['mail.thread'] name = fields.Char(string='Title', track_visibility='onchange', required=True) vehicle_id = fields.Many2one('car.car', string='Vehicle', track_visibility='onchange') user_id = fields.Many2one('res.users', string='Assigned to', select=True) active = fields.Boolean('Active') partner_id = fields.Many2one('res.partner', string='Customer') priority = fields.Selection([('0', 'Normal'), ('1', 'High')], string='Priority', select=True) description = fields.Html('Description') sequence = fields.Integer(string='Sequence', select=True, help="Gives the sequence order when displaying a list of tasks.") tag_ids = fields.Many2many('worksheet.tags', string='Tags') kanban_state = fields.Selection( [('normal', 'In Progress'), ('done', 'Ready for next stage'), ('blocked', 'Blocked')], string='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', 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', 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, readonly=True) 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, copy=False, readonly=True) id = fields.Integer(string='ID', readonly=True) color = fields.Integer(string='Color Index') company_id = fields.Many2one('res.company', string='Company', default=lambda self: self.env['res.company']._company_default_get('car.workshop')) stage_id = fields.Many2one('worksheet.stages', string='Stage', track_visibility='onchange', 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) 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") include_materials = fields.Boolean('Incluir') _defaults = { 'stage_id': 1, 'vehicle_id': lambda self, cr, uid, ctx=None: ctx.get('default_vehicle_id') if ctx is not None else False, 'date_last_stage_update': fields.datetime.now(), 'kanban_state': 'normal', 'priority': '0', 'sequence': 10, 'active': True, 'user_id': lambda obj, cr, uid, ctx=None: uid, 'partner_id': lambda self, cr, uid, ctx=None: self._get_default_vehicle(cr, uid, context=ctx), 'date_start': fields.datetime.now(), } @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 if self.include_materials==True: for line2 in hour.materials_used: amount_totall += line2.price records.amount_total = amount_totall @api.multi def cancel(self): self.state = 'cancel' @api.multi def workshop_create_invoices(self): self.state = 'workshop_create_invoices' inv_obj = self.env['account.invoice'] inv_line_obj = self.env['account.invoice.line'] customer = self.partner_id if not customer.name: raise osv.except_osv(_('UserError!'), _('Please select a Customer.')) company_id = self.env['res.users'].browse(1).company_id currency_value = company_id.currency_id.id self.ensure_one() ir_values = self.env['ir.values'] journal_id = ir_values.get_default('workshop.config.setting', 'invoice_journal_type') if not journal_id: journal_id = 1 inv_data = { 'name': customer.name, 'reference': customer.name, 'account_id': customer.property_account_receivable.id, 'partner_id': customer.id, 'currency_id': currency_value, 'journal_id': journal_id, 'origin': self.name, 'company_id': company_id.id, } inv_id = inv_obj.create(inv_data) for records in self.planned_works: if records.planned_work.id: income_account = records.planned_work.property_account_income.id if not income_account: raise osv.except_osv(_('UserError!'), _('There is no income account defined ' 'for this product: "%s".') % (records.planned_work.name,)) inv_line_data = { 'name': records.planned_work.name, 'account_id': income_account, 'price_unit': records.work_cost, 'quantity': 1, 'product_id': records.planned_work.id, 'invoice_id': inv_id.id, } inv_line_obj.create(inv_line_data) for records in self.materials_used: if records.material.id: income_account = records.material.property_account_income.id if not income_account: raise osv.except_osv(_('UserError!'), _('There is no income account defined ' 'for this product: "%s".') % (records.material.name,)) if self.include_materials==True: inv_line_data = { 'name': records.material.name, 'account_id': records.material.property_account_income.id, 'price_unit': records.price, 'quantity': records.amount, 'product_id': records.material.id, 'invoice_id': inv_id.id, } inv_line_obj.create(inv_line_data) imd = self.env['ir.model.data'] action = imd.xmlid_to_object('account.action_invoice_tree1') list_view_id = imd.xmlid_to_res_id('account.invoice_tree') form_view_id = imd.xmlid_to_res_id('account.invoice_form') result = { 'name': action.name, 'help': action.help, 'type': 'ir.actions.act_window', 'views': [[list_view_id, 'tree'], [form_view_id, 'form'], [False, 'graph'], [False, 'kanban'], [False, 'calendar'], [False, 'pivot']], 'target': action.target, 'context': action.context, 'res_model': 'account.invoice', } 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 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 _track_subtype(self, cr, uid, ids, init_values, context=None): record = self.browse(cr, uid, ids[0], context=context) if 'kanban_state' in init_values and record.kanban_state == 'blocked': return 'fleet_car_workshop.mt_task_blocked' elif 'kanban_state' in init_values and record.kanban_state == 'done': return 'fleet_car_workshop.mt_task_ready' elif 'user_id' in init_values and record.user_id: # assigned -> new return '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 return 'fleet_car_workshop.mt_task_new' elif 'stage_id' in init_values: return 'fleet_car_workshop.mt_task_stage' return super(CarWorkshop, self)._track_subtype(cr, uid, ids, init_values, context=context) def create(self, cr, uid, vals, context=None): context = dict(context or {}) if vals.get('vehicle_id') and not context.get('default_vehicle_id'): context['default_vehicle_id'] = vals.get('vehicle_id') if vals.get('user_id'): vals['date_assign'] = fields.datetime.now() create_context = dict(context, mail_create_nolog=True) work_id = super(CarWorkshop, self).create(cr, uid, vals, context=create_context) return work_id # def write(self, cr, uid, ids, vals, context=None): if isinstance(ids, (int, long)): ids = [ids] if 'stage_id' in vals: vals['date_last_stage_update'] = fields.datetime.now() vals['date_assign'] = fields.datetime.now() if vals and not'kanban_state' in vals and 'stage_id' in vals: new_stage = vals.get('stage_id') vals_reset_kstate = dict(vals, kanban_state='normal') for t in self.browse(cr, uid, ids, context=context): write_vals = vals_reset_kstate if t.stage_id.id != new_stage else vals super(CarWorkshop, self).write(cr, uid, [t.id], write_vals, context=context) result = True else: result = super(CarWorkshop, self).write(cr, uid, ids, vals, context=context) return result def _read_group_stages(self, cr, uid, ids, domain, read_group_order=None, access_rights_uid=None, context=None): if context is None: context = {} stage_obj = self.pool.get('worksheet.stages') order = stage_obj._order access_rights_uid = access_rights_uid or uid if read_group_order == 'stage_id desc': order = '%s desc' % order if 'default_vehicle_id' in context: search_domain = ['|', ('vehicle_ids', '=', context['default_vehicle_id']), ('id', 'in', ids)] else: search_domain = [('id', 'in', ids)] stage_ids = stage_obj._search(cr, uid, search_domain, order=order, access_rights_uid=access_rights_uid, context=context) result = stage_obj.name_get(cr, access_rights_uid, stage_ids, context=context) # restore order of the search result.sort(lambda x, y: cmp(stage_ids.index(x[0]), stage_ids.index(y[0]))) fold = {} for stage in stage_obj.browse(cr, access_rights_uid, stage_ids, context=context): fold[stage.id] = stage.fold or False return result, fold _group_by_full = { 'stage_id': _read_group_stages, } @api.cr_uid_ids_context def onchange_vehicle(self, cr, uid, id, vehicle_id, context=None): values = {} if vehicle_id: vehicle = self.pool.get('fleet.vehicle').browse(cr, uid, vehicle_id, context=context) if vehicle.exists(): values['partner_id'] = vehicle.partner_id.id else: values['stage_id'] = False return {'value': values} def _get_default_vehicle(self, cr, uid, context=None): if context is None: context = {} if 'default_vehicle_id' in context: vehicle = self.pool.get('car.car').browse(cr, uid, context['default_vehicle_id'], context=context) if vehicle and vehicle.partner_id: return vehicle.partner_id.id return False