Пример #1
0
class hr_warning(models.Model):

    _name = 'hr.infraction.warning'
    _description = 'Employee Warning'
    _columns = {
        'name': fields.char(
            'Subject',
            size=256,
        ),
        'date': fields.date(
            'Date Issued',
        ),
        'type': fields.selection(
            [
                ('verbal', 'Verbal'),
                ('written', 'Written'),
            ],
            'Type',
            required=True,
        ),
        'action_id': fields.many2one(
            'hr.infraction.action',
            'Action',
            ondelete='cascade',
            readonly=True,
        ),
        'infraction_id': fields.related(
            'action_id',
            'infraction_id',
            type='many2one',
            obj='hr.infraction',
            string='Infraction',
            readonly=True,
        ),
        'employee_id': fields.related(
            'infraction_id',
            'employee_id',
            type='many2one',
            obj='hr.employee',
            string='Employee',
            readonly=True,
        ),
    }

    _defaults = {
        'type': 'written',
        'date': time.strftime(DEFAULT_SERVER_DATE_FORMAT),
    }

    def unlink(self, cr, uid, ids, context=None):
        for warning in self.browse(cr, uid, ids, context=context):
            if (warning.action_id
                    and warning.action_id.infraction_id.state != 'draft'):
                raise models.except_orm(
                    _('Error'),
                    _('Warnings attached to Infractions not in "Draft" state '
                      'may not be removed.')
                )
        return super(hr_warning, self).unlink(cr, uid, ids, context=context)
Пример #2
0
class patient_data (osv.osv):
	_name = "medical.patient"
	_inherit = "medical.patient"

	_columns = {
		'receivable' : fields.related('name','credit',type='float',string='Receivable',help='Total amount this patient owes you',readonly=True),
	}
Пример #3
0
class pos_stock_inventory_categ_detail_line(osv.osv):
    _name = 'pos.stock.inventory.categ.detail.line'
    _description = 'Detalle del Inventario por Categoria'
    _rec_name = 'product_id'
    _columns = {
        'ref_id':
        fields.many2one('pos.stock.inventory.categ.detail', 'ID Ref'),
        'location_id':
        fields.many2one(
            'stock.location',
            'Ubicacion',
        ),
        'product_id':
        fields.many2one('product.product', 'Producto'),
        'product_uom_id':
        fields.many2one(
            'product.uom',
            'Unidad Base',
        ),
        'product_qty':
        fields.float('Cantidad', digits=(14, 2)),
        'default_code':
        fields.related('product_id',
                       'default_code',
                       type='char',
                       string='Codigo Interno',
                       readonly=True),
    }
    _defaults = {}
    _order = 'id'
Пример #4
0
class stock_move(osv.osv):
    _inherit = 'stock.move'
    _columns = {
        'default_code':
        fields.related('product_id',
                       'default_code',
                       type='char',
                       string='Internal Reference'),
    }
Пример #5
0
class sale_order_line(osv.osv):

    _inherit = 'sale.order.line'
    _columns = {
        'default_code':
        fields.related('product_id',
                       'default_code',
                       type='char',
                       string='Internal Reference'),
    }
Пример #6
0
class account_invoice_line(osv.osv):

    _inherit = 'account.invoice.line'
    _columns = {
        'default_code':
        fields.related('product_id',
                       'default_code',
                       type='char',
                       string='Internal Reference'),
    }
Пример #7
0
class hr_infraction_action(models.Model):

    _name = 'hr.infraction.action'
    _description = 'Action Based on Infraction'
    _columns = {
        'infraction_id': fields.many2one(
            'hr.infraction',
            'Infraction',
            ondelete='cascade',
            required=True,
            readonly=True,
        ),
        'type': fields.selection(
            ACTION_TYPE_SELECTION,
            'Type',
            required=True,
        ),
        'memo': fields.text(
            'Notes',
        ),
        'employee_id': fields.related(
            'infraction_id',
            'employee_id',
            type='many2one',
            store=True,
            obj='hr.employee',
            string='Employee',
            readonly=True,
        ),
        'warning_id': fields.many2one(
            'hr.infraction.warning',
            'Warning',
            readonly=True,
        ),
        'transfer_id': fields.many2one(
            'hr.department.transfer',
            'Transfer',
            readonly=True,
        ),
    }
    _rec_name = 'type'

    def unlink(self, cr, uid, ids, context=None):

        for action in self.browse(cr, uid, ids, context=context):
            if action.infraction_id.state not in ['draft']:
                raise models.except_orm(
                    _('Error'),
                    _('Actions belonging to Infractions not in "Draft" state '
                      'may not be removed.')
                )

        return super(hr_infraction_action, self).unlink(
            cr, uid, ids, context=context
        )
Пример #8
0
class hr_contract(models.Model):

    _name = 'hr.contract'
    _inherit = 'hr.contract'
    _columns = {
        'is_labour_union':
        fields.related(
            'employee_id',
            'is_labour_union',
            type='boolean',
            store=True,
            string='Labour Union Member',
        ),
    }
Пример #9
0
class stock_inventory_line(osv.osv):
    _name = 'stock.inventory.line'
    _inherit = 'stock.inventory.line'
    _columns = {
        'product_category':
        fields.related('product_id',
                       'categ_id',
                       type="many2one",
                       relation="product.category",
                       string='Categoria',
                       store=True),
    }

    _defaults = {}
Пример #10
0
class custom_calendar_event(osv.osv):
    _name = "calendar.event"
    _inherit = 'calendar.event'


    @api.depends('x_categ_id','x_partner_id')
    def _compute_categ_id_char(self):
        self.x_categ_id_char = self.x_categ_id.name
        if self.x_categ_id_char and self.x_partner_id.display_name and self.x_partner_id.phone:
            self.name = self.x_categ_id_char+' : '+self.x_partner_id.display_name+', '+self.x_partner_id.phone
        elif self.x_categ_id_char and self.x_partner_id.display_name:
            self.name = self.x_categ_id_char+' : '+self.x_partner_id.display_name
        elif self.x_partner_id.display_name:
            self.name = self.x_partner_id.display_name
        elif self.x_categ_id_char:
            self.name = self.x_categ_id_char
        else:
  
            
    _columns = {
        'x_domicile': fields.boolean('A domicile'),
        'x_partner_id': fields.many2one('res.partner', 'Attendee', default=''),
        'x_categ_id': fields.many2one('calendar.event.type', 'Tags'),
        'x_categ_id_char': fields.char(compute='_compute_categ_id_char', default=''),
        'x_event_is_billed': fields.boolean('is_billed'),
        'x_event_is_printed': fields.boolean('is_printed'),

        # related field res.partner 
        # -------------------------
        'x_event_display_name' : fields.related('x_partner_id', 'display_name', type="char"),
        'x_event_name' : fields.related('x_partner_id', 'name', type="char"),
        'x_event_phone' : fields.related('x_partner_id', 'phone', type="char", default=''),
        'x_event_patient_prenom': fields.related('x_partner_id', 'x_patient_prenom', type="char"),
        'x_event_patient_sexe': fields.related('x_partner_id', 'x_patient_sexe', type="selection", selection=SEXE_SELECTION),
        'x_event_patient_cafat': fields.related('x_partner_id', 'x_patient_cafat', type="char"),
        'x_event_dob': fields.date(related='x_partner_id.dob'),
        'x_event_age' : fields.integer(related='x_partner_id.age'),
        'x_event_src_avatar' : fields.binary(related='x_partner_id.x_src_avatar'),
        'x_event_medecin_traitant': fields.char(related='x_partner_id.x_medecin_traitant'),
        ########## MEDICAL INFO ???
        # 'x_event_groupe_sang': fields.related('x_partner_id', 'x_groupe_sang', type="selection", selection=GRP_SANG_SELECTION),
        # 'x_event_taille': fields.float(related='x_partner_id.x_taille'),
        # 'x_event_poids': fields.float(related='x_partner_id.x_poids'),
        # 'x_event_IMC': fields.float(related='x_partner_id.x_IMC'),
        ##########
        
        
        # related field calendar_event_type 
        # -------------------------
        'x_event_codeActe': fields.char(related='x_categ_id.x_code_acte', size=8),
        'x_event_priceActe': fields.float(related='x_categ_id.x_price_acte', digits=(4,0)),
        # -------------------------
    }
    _default = {
        'x_domicile': False,
    }
Пример #11
0
class stock_move(osv.osv):
    _inherit = 'stock.move'
    
    _columns = {
        'picking_type_code': fields.related('picking_type_id', 'code', type='char', string='Picking Type Code', help="Technical field used to display the correct label on print button in the picking view"),
        'location_dest_asset': fields.related('location_dest_id', 'asset_location', type='boolean', string='Destination Asset Location', readonly="1"),
        'location_asset': fields.related('location_id', 'asset_location', type='boolean', string='Source Asset Location', readonly="1"),
        'asset_category_id': fields.many2one('account.asset.category', "Asset Category", domain=[('asset_type','=','fixed')]),
        'asset_id': fields.many2one('account.asset.asset', "Asset"),
        'asset_ids': fields.one2many('account.asset.asset', 'stock_move_id', "Assets", readonly="1"),
    }
    
    def onchange_picking_type_id(self, cr, uid, ids, picking_type_id=False, context=None):
        if not picking_type_id:
            return {}
        res = {}
        pick_type = self.pool.get('stock.picking.type').browse(cr, uid, picking_type_id, context=context)
        res['picking_type_code'] = str(pick_type.code)
        return {'value': res}
        
    def onchange_location_asset(self, cr, uid, ids, location_id=False, context=None):
        if not location_id:
            return {}
        res = {}
        location = self.pool.get('stock.location').browse(cr, uid, location_id, context=context)
        res['location_asset'] = location.asset_location
        return {'value': res}
        
    def onchange_location_dest_asset(self, cr, uid, ids, location_dest_id=False, context=None):
        if not location_dest_id:
            return {}
        res = {}
        location = self.pool.get('stock.location').browse(cr, uid, location_dest_id, context=context)
        res['location_dest_asset'] = location.asset_location
        return {'value': res}
        
    def onchange_asset_category_id(self, cr, uid, ids, asset_category_id=False, pick_type_id=False, context=None):
        if not asset_category_id:
            return {}
        res = {}
        if pick_type_id:
            pick_type = self.pool.get('stock.picking.type').browse(cr, uid, pick_type_id, context=context)
            dest_location_id = pick_type.warehouse_id and pick_type.warehouse_id.wh_asset_loc_id and pick_type.warehouse_id.wh_asset_loc_id.id or False
            res['location_dest_id'] = dest_location_id
        return {'value': res}
        
    def action_done(self, cr, uid, ids, context=None):
        super(stock_move, self).action_done(cr, uid, ids, context)
        context = context or {}
        asset_obj = self.pool.get('account.asset.asset')
        for move in self.browse(cr, uid, ids, context=context):
            if move.asset_category_id and not move.asset_ids:
                purchase_date = move.date
                partner_id = move.partner_id and move.partner_id.id or False
                purchase_value = move.price_unit
                category_id = move.asset_category_id
                if category_id.prorata:
                    purchase_date = move.date
                else:
                    purchase_date = datetime.strptime(move.date[:10],"%Y-%m-%d") + relativedelta(day=1, months=+1)
                vals = {
                    'name': move.product_id.name,
                    'category_id': category_id.id,
                    'asset_type': category_id.asset_type,
                    'code': move.product_id.name or False,
                    'purchase_value': purchase_value,
                    'inventory_value' : purchase_value,
                    'purchase_date': purchase_date,
                    'partner_id': partner_id,
                    'entry_date': move.date,
                    'product_id': move.product_id.id,
                    'stock_move_id': move.id,
                    'picking_id':move.picking_id and move.picking_id.id or False,
                    'state': 'draft',
                }
                
                if move.quant_ids:
                    for quant in move.quant_ids:
                        lot_id = quant.lot_id and quant.lot_id.id or False
                        vals['prodlot_id'] = lot_id
                        qty = quant.qty
                        while qty > 0:
                            qty -= 1
                            changed_vals = asset_obj.onchange_category_id(cr, uid, [], vals['category_id'], context=context)
                            vals.update(changed_vals['value'])
                            asset_id = asset_obj.create(cr, uid, vals, context=context)
        return True
        
    def action_cancel(self, cr, uid, ids, context=None):
        """ Try to cancel the assets linked with this stock move if they are in draft state """
        context = context or {}
        for move in self.browse(cr, uid, ids, context=context):
            if move.asset_category_id and move.asset_ids:
                for asset in move.asset_ids:
                    if asset.state <> 'draft':
                        raise except_orm(_('Error!'), _("You cannot cancel a stock move which doesn't have assets in draft state. You need to reset to draft the asset with name %s." % asset.name)) 
                move.asset_ids.unlink()
        return super(stock_move, self).action_cancel(cr, uid, ids, context=context)
    
    def action_assign(self, cr, uid, ids, context=None):
        """ Checks the product type and accordingly writes the state.
        """
        context = context or {}
        quant_obj = self.pool.get("stock.quant")
        to_assign_moves = []
        main_domain = {}
        todo_moves = []
        operations = set()
        for move in self.browse(cr, uid, ids, context=context):
            if move.asset_id:
                if move.state not in ('confirmed', 'waiting', 'assigned'):
                    continue
                if move.location_id.usage in ('supplier', 'inventory', 'production'):
                    to_assign_moves.append(move.id)
                    #in case the move is returned, we want to try to find quants before forcing the assignment
                    if not move.origin_returned_move_id:
                        continue
                if move.product_id.type == 'consu':
                    to_assign_moves.append(move.id)
                    continue
                else:
                    todo_moves.append(move)

                    #we always keep the quants already assigned and try to find the remaining quantity on quants not assigned only
                    main_domain[move.id] = [('history_ids', 'in', move.asset_id.stock_move_id.id),('reservation_id', '=', False), ('qty', '>', 0)]

                    #if the move is preceeded, restrict the choice of quants in the ones moved previously in original move
                    ancestors = self.find_move_ancestors(cr, uid, move, context=context)
                    if move.state == 'waiting' and not ancestors:
                        #if the waiting move hasn't yet any ancestor (PO/MO not confirmed yet), don't find any quant available in stock
                        main_domain[move.id] += [('id', '=', False)]
                    elif ancestors:
                        main_domain[move.id] += [('history_ids', 'in', ancestors)]

                    #if the move is returned from another, restrict the choice of quants to the ones that follow the returned move
                    if move.origin_returned_move_id:
                        main_domain[move.id] += [('history_ids', 'in', move.origin_returned_move_id.id)]
                    for link in move.linked_move_operation_ids:
                        operations.add(link.operation_id)
                # Check all ops and sort them: we want to process first the packages, then operations with lot then the rest
                operations = list(operations)
                operations.sort(key=lambda x: ((x.package_id and not x.product_id) and -4 or 0) + (x.package_id and -2 or 0) + (x.lot_id and -1 or 0))
                for ops in operations:
                    #first try to find quants based on specific domains given by linked operations
                    for record in ops.linked_move_operation_ids:
                        move = record.move_id
                        if move.id in main_domain:
                            domain = main_domain[move.id] + self.pool.get('stock.move.operation.link').get_specific_domain(cr, uid, record, context=context)
                            qty = record.qty
                            if qty:
                                quants = quant_obj.quants_get_prefered_domain(cr, uid, ops.location_id, move.product_id, qty, domain=domain, prefered_domain_list=[], restrict_lot_id=move.restrict_lot_id.id, restrict_partner_id=move.restrict_partner_id.id, context=context)
                                quant_obj.quants_reserve(cr, uid, quants, move, record, context=context)
                for move in todo_moves:
                    move.refresh()
                    #then if the move isn't totally assigned, try to find quants without any specific domain
                    if move.state != 'assigned':
                        qty_already_assigned = move.reserved_availability
                        qty = move.product_qty - qty_already_assigned
                        quants = quant_obj.quants_get_prefered_domain(cr, uid, move.location_id, move.product_id, qty, domain=main_domain[move.id], prefered_domain_list=[], restrict_lot_id=move.restrict_lot_id.id, restrict_partner_id=move.restrict_partner_id.id, context=context)
                        quant_obj.quants_reserve(cr, uid, quants, move, context=context)

                #force assignation of consumable products and incoming from supplier/inventory/production
                if to_assign_moves:
                    self.force_assign(cr, uid, to_assign_moves, context=context)
            else:    
                super(stock_move, self).action_assign(cr, uid, ids, context=context)
Пример #12
0
class AccountVoucher(osv.osv):
    _inherit = "account.voucher"
    
    @api.one
    @api.depends('currency_id', 'payment_rate_currency_id', 'payment_rate', 'amount', 'date', 'journal_id')
    def _compute_rate_amount(self):
        print "--_compute_rate_amount-"
        if self.currency_id != self.payment_rate_currency_id:
            currency_obj = self.env['res.currency']
            currency_str = payment_rate_str = ''
            if self.currency_id:
                currency_str = currency_obj.browse(self.currency_id.id)
            if self.payment_rate_currency_id:
                payment_rate_str = currency_obj.browse(self.payment_rate_currency_id.id)
            #currency_payment = currency_obj.browse(self.currency_id.id)#.rate
            amount_curr = u'%s\N{NO-BREAK SPACE}%s' % (currency_str.symbol, locale.format("%d", payment_rate_str.rate, grouping=True))#formatLang(self.env, currency_payment.rate, currency_obj=self.currency_id)
            amount_curr_payment = u'%s\N{NO-BREAK SPACE}%s' % (payment_rate_str.symbol, locale.format("%d", currency_str.rate, grouping=True))
            #print "====",self.date,currency_str.rate,payment_rate_str.rate
            currency_help_label = _('The exchange rate was %s = %s') % (amount_curr, amount_curr_payment)
            self.amount_info = self.amount * currency_str.rate
            self.currency_inverse_help_label = currency_help_label
    
    def _get_currency_help_label(self, cr, uid, currency_id, payment_rate, payment_rate_currency_id, context=None):
        rml_parser = report_sxw.rml_parse(cr, uid, 'currency_help_label', context=context)
        currency_pool = self.pool.get('res.currency')
        currency_str = payment_rate_str = ''
        if currency_id:
            currency_str = rml_parser.formatLang(1, currency_obj=currency_pool.browse(cr, uid, currency_id, context=context))
        if payment_rate_currency_id:
            payment_rate_str  = rml_parser.formatLang(currency_pool.browse(cr, uid, currency_id, context=context).rate, currency_obj=currency_pool.browse(cr, uid, payment_rate_currency_id, context=context))
        currency_help_label = _('At the operation date, the exchange rate was\n%s = %s') % (currency_str, payment_rate_str)
        return currency_help_label

    def _fnct_currency_help_label(self, cr, uid, ids, name, args, context=None):
        res = {}
        for voucher in self.browse(cr, uid, ids, context=context):
            res[voucher.id] = self._get_currency_help_label(cr, uid, voucher.currency_id.id, voucher.payment_rate, voucher.company_currency_id.id, context=context)
        return res
    
    def _get_amount_help_label(self, cr, uid, currency_id, payment_rate, payment_rate_currency_id, context=None):
#         rml_parser = report_sxw.rml_parse(cr, uid, 'currency_help_label', context=context)
        currency_pool = self.pool.get('res.currency')
#         currency_str = payment_rate_str = ''
        if currency_id:
            #print "=======",currency_pool.browse(cr, uid, currency_id, context=context).rate
#             currency_str = rml_parser.formatLang(1, currency_obj=currency_pool.browse(cr, uid, currency_id, context=context))
#         if payment_rate_currency_id:
#             payment_rate_str  = rml_parser.formatLang(currency_pool.browse(cr, uid, currency_id, context=context).rate, currency_obj=currency_pool.browse(cr, uid, payment_rate_currency_id, context=context))
#         currency_help_label = _('At the operation date, the exchange rate was\n%s = %s') % (currency_str, payment_rate_str)
            return str(payment_rate*currency_pool.browse(cr, uid, currency_id, context=context).rate)
    
    def _fnct_amount_info_label(self, cr, uid, ids, name, args, context=None):
        res = {}        
        for voucher in self.browse(cr, uid, ids, context=context):
            res[voucher.id] = self._get_amount_help_label(cr, uid, voucher.currency_id.id, voucher.amount, voucher.company_currency_id.id, context=context)
        return res
    
    _columns = {
        'is_currency': fields.boolean('Is multi currency'),
        'amount_info': fields.function(_fnct_amount_info_label, type='float', string='Amount Rate'),
        'currency_inverse_help_label': fields.text('Rate'),
        'company_currency_id': fields.related('company_id','currency_id', type='many2one', relation='res.currency', string='Company Currency'),
        'currency_help_label': fields.function(_fnct_currency_help_label, type='text', string="Helping Sentence", help="This sentence helps you to know how to specify the payment rate by giving you the direct effect it has"), 
    }
#     is_currency = fields.Boolean('Is multi currency')
#     amount_info = fields.Float(string='Amount Rate', compute='_compute_rate_amount') 
#     currency_inverse_help_label = fields.Text(string='Helping Rate Sentence', compute='_compute_rate_amount')
    def onchange_rate(self, cr, uid, ids, rate, amount, currency_id, payment_rate_currency_id, company_id, context=None):
        company_currency = self.pool.get('res.company').browse(cr, uid, company_id, context=context).currency_id
        #currency_pool = self.pool.get('res.currency')
        #rate_view = currency_pool.browse(cr, uid, currency_id, context=context).rate
        #print "==onchange_rate==",amount,rate,rate_view,amount*rate_view
        res =  {'value': {'paid_amount_in_company_currency': amount, 'amount_info':  self._get_amount_help_label(cr, uid, currency_id, amount, company_currency.id, context=context), 'currency_help_label': self._get_currency_help_label(cr, uid, currency_id, rate, payment_rate_currency_id, context=context)}}
        if rate and amount and currency_id:
            company_currency = self.pool.get('res.company').browse(cr, uid, company_id, context=context).currency_id
            #context should contain the date, the payment currency and the payment rate specified on the voucher
            amount_in_company_currency = self.pool.get('res.currency').compute(cr, uid, currency_id, company_currency.id, amount, context=context)
            res['value']['paid_amount_in_company_currency'] = amount_in_company_currency
        return res
        
    def onchange_journal(self, cr, uid, ids, journal_id, line_ids, tax_id, partner_id, date, amount, ttype, company_id, context=None):
        if context is None:
            context = {}
        if not journal_id:
            return False
        journal_pool = self.pool.get('account.journal')
        journal = journal_pool.browse(cr, uid, journal_id, context=context)
        if ttype in ('sale', 'receipt'):
            account_id = journal.default_debit_account_id
        elif ttype in ('purchase', 'payment'):
            account_id = journal.default_credit_account_id
        else:
            account_id = journal.default_credit_account_id or journal.default_debit_account_id
        tax_id = False
        if account_id and account_id.tax_ids:
            tax_id = account_id.tax_ids[0].id
 
        vals = {'value':{} }
        if ttype in ('sale', 'purchase'):
            vals = self.onchange_price(cr, uid, ids, line_ids, tax_id, partner_id, context)
            vals['value'].update({'tax_id':tax_id,'amount': amount})
        currency_id = False
        if journal.currency:
            currency_id = journal.currency.id
        else:
            currency_id = journal.company_id.currency_id.id
 
        period_ids = self.pool['account.period'].find(cr, uid, dt=date, context=dict(context, company_id=company_id))
        is_currency = False
        if journal.currency.id and journal.currency.id != journal.company_id.currency_id.id:
            is_currency = True
        #print "===is_currency====",is_currency,journal.currency.id,journal.company_id.currency_id.id
        vals['value'].update({
            'currency_id': currency_id,
            'payment_rate_currency_id': currency_id,
            'is_currency': is_currency,
            'period_id': period_ids and period_ids[0] or False
        })
        #in case we want to register the payment directly from an invoice, it's confusing to allow to switch the journal 
        #without seeing that the amount is expressed in the journal currency, and not in the invoice currency. So to avoid
        #this common mistake, we simply reset the amount to 0 if the currency is not the invoice currency.
        if context.get('payment_expected_currency') and currency_id != context.get('payment_expected_currency'):
            vals['value']['amount'] = 0
            amount = 0
        if partner_id:
            res = self.onchange_partner_id(cr, uid, ids, partner_id, journal_id, amount, currency_id, ttype, date, context)
            for key in res.keys():
                vals[key].update(res[key])
        return vals
Пример #13
0
class custom_stock_serial(osv.osv):
    _inherit = 'stock.production.lot'
    _columns = {
        'company':
        fields.related('product_id',
                       'company_id',
                       relation="res.company",
                       type='many2one',
                       string="Company",
                       store=True),
        'status':
        fields.selection([('Available', 'Available'), ('Issued', 'Issued')],
                         string='Status',
                         store=True),
        'chassis_number':
        fields.char('Chassis No.', store=True),
        'color':
        fields.char('Color', store=True, compute='fetch_color'),
        'model':
        fields.char(string='Model', store=True),
        'year':
        fields.selection([
            ('2010', '2010'),
            ('2011', '2011'),
            ('2012', '2012'),
            ('2013', '2013'),
            ('2014', '2014'),
            ('2015', '2015'),
            ('2016', '2016'),
            ('2017', '2017'),
            ('2018', '2018'),
            ('2019', '2019'),
            ('2020', '2020'),
            ('2021', '2021'),
            ('2022', '2022'),
            ('2023', '2023'),
            ('2024', '2024'),
            ('2025', '2025'),
            ('2026', '2026'),
            ('2027', '2027'),
        ],
                         string='Year',
                         store=True),
    }

    _defaults = {
        'status': 'Available',
        'name': 'SAE-',
        'chassis_number': 'SAC-',
        'model': '70 CC',
        'year': '2018'
    }

    @api.constrains('name')
    def _check_unique_constraint(self):
        if len(
                self.search([('name', '=', self.name),
                             ('company', '=', self.company.id)])) > 1:
            raise ValidationError(
                "This engine number already exists and violates unique field constraint"
            )

    @api.constrains('chassis_number')
    def _check_unique_constraint_(self):
        if len(
                self.search([('name', '=', self.name),
                             ('company', '=', self.company.id)])) > 1:
            raise ValidationError(
                "This chassis number already exists and violates unique field constraint"
            )

    @api.one
    @api.depends('product_id')
    def fetch_color(self):
        products = [
            1856, 1850, 1851, 1852, 1853, 1854, 1855, 1857, 1858, 1862, 1980,
            1981, 1982, 1983, 1984, 1985, 1986, 1987
        ]
        if self.product_id and self.product_id.id in products:
            color = ''
            attribute = (
                self.product_id.attribute_value_ids[0].name).split(' ')
            if attribute[0] == 'Durbi' or attribute[0] == 'Smart' or attribute[
                    0] == 'Self':
                for _color in attribute:
                    color += _color + " "
            self.color = color
Пример #14
0
class hr_transfer(models.Model):

    _name = 'hr.department.transfer'
    _description = 'Departmental Transfer'

    _inherit = ['mail.thread', 'ir.needaction_mixin']

    _columns = {
        'employee_id':
        fields.many2one('hr.employee',
                        'Employee',
                        required=True,
                        readonly=True,
                        states={'draft': [('readonly', False)]}),
        'src_id':
        fields.many2one('hr.job',
                        'From',
                        required=True,
                        readonly=True,
                        states={'draft': [('readonly', False)]}),
        'dst_id':
        fields.many2one('hr.job',
                        'Destination',
                        required=True,
                        readonly=True,
                        states={'draft': [('readonly', False)]}),
        'src_department_id':
        fields.related('src_id',
                       'department_id',
                       type='many2one',
                       relation='hr.department',
                       string='From Department',
                       store=True,
                       readonly=True),
        'dst_department_id':
        fields.related('dst_id',
                       'department_id',
                       type='many2one',
                       relation='hr.department',
                       store=True,
                       string='Destination Department',
                       readonly=True),
        'src_contract_id':
        fields.many2one('hr.contract',
                        'From Contract',
                        readonly=True,
                        states={'draft': [('readonly', False)]}),
        'dst_contract_id':
        fields.many2one('hr.contract', 'Destination Contract', readonly=True),
        'date':
        fields.date('Effective Date',
                    required=True,
                    readonly=True,
                    states={'draft': [('readonly', False)]}),
        'state':
        fields.selection([
            ('draft', 'Draft'),
            ('confirm', 'Confirmed'),
            ('pending', 'Pending'),
            ('done', 'Done'),
            ('cancel', 'Cancelled'),
        ],
                         'State',
                         readonly=True),
    }

    _rec_name = 'date'

    _defaults = {
        'state': 'draft',
    }

    _track = {
        'state': {
            'hr_transfer.mt_alert_xfer_confirmed':
            lambda self, cr, uid, obj, ctx=None: obj['state'] == 'confirm',
            'hr_transfer.mt_alert_xfer_pending':
            lambda self, cr, uid, obj, ctx=None: obj['state'] == 'pending',
            'hr_transfer.mt_alert_xfer_done':
            lambda self, cr, uid, obj, ctx=None: obj['state'] == 'done',
        },
    }

    def _needaction_domain_get(self, cr, uid, context=None):

        users_obj = self.pool.get('res.users')

        if users_obj.has_group(cr, uid, 'base.group_hr_manager'):
            domain = [('state', '=', 'confirm')]
            return domain

        return False

    def unlink(self, cr, uid, ids, context=None):

        for xfer in self.browse(cr, uid, ids, context=context):
            if xfer.state not in ['draft']:
                raise models.except_orm(
                    _('Unable to Delete Transfer!'),
                    _('Transfer has been initiated. Either cancel the transfer'
                      ' or create another transfer to undo it.'))

        return super(hr_transfer, self).unlink(cr, uid, ids, context=context)

    def onchange_employee(self, cr, uid, ids, employee_id, context=None):

        res = {'value': {'src_id': False, 'src_contract_id': False}}

        if employee_id:
            ee = self.pool.get('hr.employee').browse(cr,
                                                     uid,
                                                     employee_id,
                                                     context=context)
            res['value']['src_id'] = ee.contract_id.job_id.id
            res['value']['src_contract_id'] = ee.contract_id.id

        return res

    def effective_date_in_future(self, cr, uid, ids, context=None):

        today = datetime.now().date()
        for xfer in self.browse(cr, uid, ids, context=context):
            effective_date = datetime.strptime(
                xfer.date, DEFAULT_SERVER_DATE_FORMAT).date()
            if effective_date <= today:
                return False

        return True

    def _check_state(self, cr, uid, contract_id, effective_date, context=None):

        contract_obj = self.pool.get('hr.contract')
        data = contract_obj.read(cr,
                                 uid,
                                 contract_id, ['state', 'date_end'],
                                 context=context)

        if data['state'] not in [
                'trial', 'trial_ending', 'open', 'contract_ending'
        ]:
            raise models.except_orm(
                _('Warning!'),
                _('The current state of the contract does not permit changes.')
            )

        if data.get('date_end', False) and data['date_end'] != '':
            dContractEnd = datetime.strptime(data['date_end'],
                                             DEFAULT_SERVER_DATE_FORMAT)
            dEffective = datetime.strptime(effective_date,
                                           DEFAULT_SERVER_DATE_FORMAT)
            if dEffective >= dContractEnd:
                raise models.except_orm(
                    _('Warning!'),
                    _('The contract end date is on or before the effective '
                      'date of the transfer.'))

        return True

    def transfer_contract(self,
                          cr,
                          uid,
                          contract_id,
                          job_id,
                          xfer_id,
                          effective_date,
                          context=None):

        contract_obj = self.pool.get('hr.contract')

        # Copy the contract and adjust start/end dates, job id, etc.
        # accordingly.
        #
        default = {
            'job_id': job_id,
            'date_start': effective_date,
            'name': False,
            'state': False,
            'message_ids': False,
            'trial_date_start': False,
            'trial_date_end': False,
        }
        data = contract_obj.copy_data(cr,
                                      uid,
                                      contract_id,
                                      default=default,
                                      context=context)

        c_id = contract_obj.create(cr, uid, data, context=context)
        if c_id:
            vals = {}
            wkf = netsvc.LocalService('workflow')

            # Set the new contract to the appropriate state
            wkf.trg_validate(uid, 'hr.contract', c_id, 'signal_confirm', cr)

            # Terminate the current contract (and trigger appropriate state
            # change)
            vals['date_end'] = datetime.strptime(
                effective_date, '%Y-%m-%d').date() + relativedelta(days=-1)
            contract_obj.write(cr, uid, contract_id, vals, context=context)
            wkf.trg_validate(uid, 'hr.contract', contract_id, 'signal_done',
                             cr)

            # Link to the new contract
            self.pool.get('hr.department.transfer').write(
                cr, uid, xfer_id, {'dst_contract_id': c_id}, context=context)

        return

    def state_confirm(self, cr, uid, ids, context=None):

        for xfer in self.browse(cr, uid, ids, context=context):
            self._check_state(cr,
                              uid,
                              xfer.src_contract_id.id,
                              xfer.date,
                              context=context)
            self.write(cr, uid, xfer.id, {'state': 'confirm'}, context=context)

        return True

    def state_done(self, cr, uid, ids, context=None):

        employee_obj = self.pool.get('hr.employee')
        today = datetime.now().date()

        for xfer in self.browse(cr, uid, ids, context=context):
            if datetime.strptime(xfer.date,
                                 DEFAULT_SERVER_DATE_FORMAT).date() <= today:
                self._check_state(cr,
                                  uid,
                                  xfer.src_contract_id.id,
                                  xfer.date,
                                  context=context)
                employee_obj.write(
                    cr,
                    uid,
                    xfer.employee_id.id,
                    {'department_id': xfer.dst_department_id.id},
                    context=context)
                self.transfer_contract(cr,
                                       uid,
                                       xfer.src_contract_id.id,
                                       xfer.dst_id.id,
                                       xfer.id,
                                       xfer.date,
                                       context=context)
                self.write(cr,
                           uid,
                           xfer.id, {'state': 'done'},
                           context=context)
            else:
                return False

        return True

    def try_pending_department_transfers(self, cr, uid, context=None):
        """Completes pending departmental transfers. Called from
        the scheduler."""

        xfer_obj = self.pool.get('hr.department.transfer')
        today = datetime.now().date()
        xfer_ids = xfer_obj.search(
            cr,
            uid, [
                ('state', '=', 'pending'),
                ('date', '<=', today.strftime(DEFAULT_SERVER_DATE_FORMAT)),
            ],
            context=context)

        wkf = netsvc.LocalService('workflow')
        [
            wkf.trg_validate(uid, 'hr.department.transfer', xfer.id,
                             'signal_done', cr)
            for xfer in self.browse(cr, uid, xfer_ids, context=context)
        ]

        return True
Пример #15
0
class wage_increment(models.Model):

    _name = 'hr.contract.wage.increment'
    _description = 'HR Contract Wage Adjustment'

    def _calculate_difference(self,
                              cr,
                              uid,
                              ids,
                              field_name,
                              args,
                              context=None):

        res = dict.fromkeys(ids)
        for incr in self.browse(cr, uid, ids, context=context):
            if incr.wage >= incr.contract_id.wage:
                percent = ((incr.wage / incr.contract_id.wage) - 1.0) * 100.0
            else:
                percent = (1.0 - (incr.wage / incr.contract_id.wage)) * -100.0
            res[incr.id] = {
                'wage_difference': incr.wage - incr.current_wage,
                'wage_difference_percent': percent,
            }

        return res

    def _get_department(self, cr, uid, ids, field_name, arg, context=None):

        res = dict.fromkeys(ids, False)
        for incr in self.browse(cr, uid, ids, context=context):
            res[incr.id] = incr.employee_id.department_id.id,

        return res

    _columns = {
        'effective_date':
        fields.date(
            'Effective Date',
            required=True,
            readonly=True,
            states={'draft': [('readonly', False)]},
        ),
        'wage':
        fields.float(
            'New Wage',
            digits_compute=dp.get_precision('Payroll'),
            required=True,
            readonly=True,
            states={'draft': [('readonly', False)]},
        ),
        'new_contract_id':
        fields.many2one(
            'hr.contract',
            'New Contract',
            readonly=True,
        ),
        'contract_id':
        fields.many2one(
            'hr.contract',
            'Contract',
            readonly=True,
        ),
        'current_wage':
        fields.related(
            'contract_id',
            'wage',
            type='float',
            string='Current Wage',
            store=True,
            readonly=True,
        ),
        'wage_difference':
        fields.function(
            _calculate_difference,
            type='float',
            method=True,
            string='Difference',
            multi='diff',
            readonly=True,
        ),
        'wage_difference_percent':
        fields.function(
            _calculate_difference,
            type='float',
            method=True,
            string='Percentage',
            multi='diff',
            readonly=True,
        ),
        'employee_id':
        fields.related(
            'contract_id',
            'employee_id',
            relation='hr.employee',
            type='many2one',
            string='Employee',
            store=True,
            readonly=True,
        ),
        'job_id':
        fields.related(
            'contract_id',
            'job_id',
            relation='hr.job',
            type='many2one',
            string='Job',
            store=True,
            readonly=True,
        ),
        'department_id':
        fields.related(
            'employee_id',
            'department_id',
            relation='hr.department',
            type='many2one',
            string='Department',
            store=True,
            readonly=True,
        ),
        'state':
        fields.selection(
            [('draft', 'Draft'), ('confirm', 'Confirmed'),
             ('approve', 'Approved'), ('decline', 'Declined')],
            'State',
            readonly=True,
        ),
        'run_id':
        fields.many2one(
            'hr.contract.wage.increment.run',
            'Batch Run',
            readonly=True,
            ondelete='cascade',
        ),
    }

    def _get_contract_data(self, cr, uid, field_list, context=None):

        if context is None:
            context = {}
        employee_id = self._get_employee(cr, uid, context=context)
        ee_data = self.pool.get('hr.employee').read(cr,
                                                    uid,
                                                    employee_id,
                                                    ['contract_id'],
                                                    context=context)
        contract_id = ee_data.get('contract_id', False)[0]
        if not contract_id:
            return False

        data = self.pool.get('hr.contract').read(cr,
                                                 uid,
                                                 contract_id,
                                                 field_list,
                                                 context=context)

        return data

    def _get_contract_id(self, cr, uid, context=None):

        data = self._get_contract_data(cr, uid, ['id'], context)
        return data.get('id', False)

    def _get_employee(self, cr, uid, context=None):

        if context is None:
            context = {}
        employee_id = context.get('active_id', False)

        return employee_id

    def _get_effective_date(self, cr, uid, context=None):

        contract_id = self._get_contract_id(cr, uid, context=context)
        if not contract_id:
            return False

        contract = self.pool.get('hr.contract').browse(cr,
                                                       uid,
                                                       contract_id,
                                                       context=context)
        if contract.pps_id:
            first_day = 1
            if contract.pps_id.type == 'monthly':
                first_day = contract.pps_id.mo_firstday
            date_format = '%Y-%m-' + first_day
            dThisMonth = datetime.now().strftime(date_format).strptime(
                DEFAULT_SERVER_DATE_FORMAT).date()
            dNextMonth = (datetime.now() + relativedelta(months=+1)).strftime(
                date_format).strptime(DEFAULT_SERVER_DATE_FORMAT).date()
            if dThisMonth < datetime.now().date():
                return dNextMonth.strftime(DEFAULT_SERVER_DATE_FORMAT)
            else:
                return dThisMonth.strftime(DEFAULT_SERVER_DATE_FORMAT)

        return False

    _defaults = {
        'contract_id': _get_contract_id,
        'employee_id': _get_employee,
        'effective_date': _get_effective_date,
        'state': 'draft',
    }

    _rec_name = 'effective_date'

    def _check_state(self, cr, uid, wage_incr, context=None):

        wage_incr_ids = self.search(
            cr,
            uid, [
                ('contract_id', '=', wage_incr.contract_id.id),
                ('state', 'in', ['draft', 'confirm', 'approved']),
                ('id', '!=', wage_incr.id),
            ],
            context=context)
        if len(wage_incr_ids) > 0:
            data = self.pool.get('hr.contract').read(cr,
                                                     uid,
                                                     wage_incr.contract_id.id,
                                                     ['name'],
                                                     context=context)
            raise models.except_orm(
                _('Warning'),
                _('There is already another wage adjustment in progress for '
                  'this contract: %s.') % (data['name']))

        contract_obj = self.pool.get('hr.contract')
        data = contract_obj.read(cr,
                                 uid,
                                 wage_incr.contract_id.id,
                                 ['state', 'date_end'],
                                 context=context)

        if data['state'] in ['draft', 'done']:
            data = self.pool.get('hr.contract').read(cr,
                                                     uid,
                                                     wage_incr.contract_id.id,
                                                     ['name'],
                                                     context=context)
            raise models.except_orm(
                _('Warning!'),
                _('The current state of the contract does not permit a wage '
                  'change: %s') % (data['name']))

        if data.get('date_end', False) and data['date_end'] != '':
            dContractEnd = datetime.strptime(data['date_end'],
                                             DEFAULT_SERVER_DATE_FORMAT)
            dEffective = datetime.strptime(wage_incr.effective_date,
                                           DEFAULT_SERVER_DATE_FORMAT)
            if dEffective >= dContractEnd:
                data = self.pool.get('hr.contract').read(
                    cr,
                    uid,
                    wage_incr.contract_id.id, ['name'],
                    context=context)
                raise models.except_orm(
                    _('Warning!'),
                    _('The contract end date is on or before the effective '
                      'date of the adjustment: %s') % (data['name']))
        return True

    def action_wage_increment(self, cr, uid, ids, context=None):

        hr_obj = self.pool.get('hr.contract')

        if isinstance(ids, (int, long)):
            ids = [ids]

        # Copy the contract and adjust start/end dates and wage accordingly.
        #
        for wi in self.browse(cr, uid, ids, context=context):

            if -0.01 < wi.wage_difference < 0.01:
                continue

            self._check_state(cr, uid, wi, context=context)

            default = {
                'wage': wi.wage,
                'date_start': wi.effective_date,
                'name': False,
                'state': False,
                'message_ids': False,
                'trial_date_start': False,
                'trial_date_end': False,
            }
            data = hr_obj.copy_data(cr,
                                    uid,
                                    wi.contract_id.id,
                                    default=default,
                                    context=context)
            notes = data.get('notes', False)
            if not notes:
                notes = ''
            notes = notes + \
                _('\nSuperceedes (because of wage adjustment) previous '
                  'contract: ') + wi.contract_id.name
            data['notes'] = notes

            c_id = hr_obj.create(cr, uid, data, context=context)
            if c_id:
                if wi.contract_id.notes:
                    notes = wi.contract_id.notes
                else:
                    notes = ''
                notes = notes + \
                    _('\nSuperceeded (for wage adjustment) by contract: ') + \
                    wi.contract_id.name
                vals = {'notes': notes, 'date_end': False}
                wkf = netsvc.LocalService('workflow')

                # Set the new contract to the appropriate state
                wkf.trg_validate(uid, 'hr.contract', c_id, 'signal_confirm',
                                 cr)

                # Terminate the current contract (and trigger appropriate state
                # change)
                vals['date_end'] = datetime.strptime(
                    wi.effective_date, '%Y-%m-%d').date() + \
                    relativedelta(days=-1)
                hr_obj.write(cr, uid, wi.contract_id.id, vals, context=context)
                wkf.trg_validate(uid, 'hr.contract', wi.contract_id.id,
                                 'signal_done', cr)

        return

    def create(self, cr, uid, vals, context=None):

        contract_id = vals.get('contract_id', False)

        if not contract_id:
            if context is not None:
                contract_id = context.get('active_id')

        data = self.pool.get('hr.contract').read(cr,
                                                 uid,
                                                 contract_id,
                                                 ['name', 'date_start'],
                                                 context=context)

        # Check that the contract start date is before the effective date
        if vals['effective_date'] <= data['date_start']:
            raise models.except_orm(
                _('Error'),
                _('The effective date of the adjustment must be after the '
                  'contract start date. Contract: %s.') % (data['name']))

        wage_incr_ids = self.search(
            cr,
            uid, [
                ('contract_id', '=', contract_id),
                ('state', 'in', ['draft', 'confirm', 'approved']),
            ],
            context=context)
        if len(wage_incr_ids) > 0:
            raise models.except_orm(
                _('Warning'),
                _('There is already another wage adjustment in progress for '
                  'this contract: %s.') % (data['name']))

        return super(wage_increment, self).create(cr,
                                                  uid,
                                                  vals,
                                                  context=context)

    def do_signal_confirm(self, cr, uid, ids, context=None):

        for wi in self.browse(cr, uid, ids, context=context):
            self._check_state(cr, uid, wi, context=context)
            self.write(cr, uid, wi.id, {'state': 'confirm'}, context=context)

    def do_signal_approve(self, cr, uid, ids, context=None):

        for i in ids:
            self.action_wage_increment(cr, uid, [i], context=context)
            self.write(cr, uid, i, {'state': 'approve'}, context=context)

    def unlink(self, cr, uid, ids, context=None):

        for incr in self.browse(cr, uid, ids, context=context):
            if incr.state in ['approve']:
                raise models.except_orm(
                    _('The record cannot be deleted!'),
                    _("""\
You may not delete a record that is in a %s state:
Employee: %s""") % (incr.state, incr.employee_id.name))

        return super(wage_increment, self).unlink(cr,
                                                  uid,
                                                  ids,
                                                  context=context)
Пример #16
0
    name = fields.Char('Number', required=True, copy=False)
    ref = fields.Char('Reference', copy=False)
    period_id = fields.Many2one('account.period', 'Period', required=True,
                                states={'posted =[('readonly',True)]})
    journal_id = fields.Many2one('account.journal', 'Journal', required=True,
                                 states={'posted =[('readonly',True)]})
    state = fields.Selection(
        [('draft','Unposted'), ('posted','Posted')], 'Status',
        required=True, readonly=True, copy=False,
        help='All manually created new journal entries are usually in the status \'Unposted\', '
             'but you can set the option to skip that status on the related journal. '
             'In that case, they will behave as journal entries automatically created by the '
             'system on document validation (invoices, bank statements...) and will be created '
             'in \'Posted\' status.'),
    line_id = fields.One2many('account.move.line', 'move_id', 'Entries',
        states={'posted =[('readonly',True)]},

    reversal_id = fields.Char('Reversal Entry')
    to_be_reversed = fields.Boolean('To Be Reversed')

    to_check = fields.Boolean('To Review', help='Check this box if you are unsure of that journal entry and if you want to note it as \'to be reviewed\' by an accounting expert.'),
               partner_id = fields.Related('line_id', 'partner_id', type="many2one", relation="res.partner", string="Partner", store={
        _name: (lambda self, cr,uid,ids,c: ids, ['line_id'], 10)
        'account.move.line = (_get_move_from_lines, ['partner_id'],10)
    }),
    amount = fields.Function(_amount_compute, string='Amount', digits_compute=dp.get_precision('Account'), type='float', fnct_search=_search_amount),
                                     date = fields.date('Date', required=True, states={'posted =[('readonly',True)]}, select=True),
    narration =fields.Text('Internal Note'), \
               company_id = fields.related('journal_id','company_id',type='many2one',relation='res.company',string='Company', store=True, readonly=True), \
                            balance = fields.Float('balance', digits_compute=dp.get_precision('Account'), help="This is a field only used for internal purpose and shouldn't be displayed"),
Пример #17
0
class restday(models.TransientModel):

    _name = 'hr.restday.wizard'
    _description = 'Schedule Template Change Wizard'

    _columns = {
        'employee_id':
        fields.many2one(
            'hr.employee',
            'Employee',
            required=True,
        ),
        'contract_id':
        fields.related(
            'employee_id',
            'contract_id',
            type='many2one',
            relation='hr.contract',
            string='Contract',
            readonly=True,
        ),
        'st_current_id':
        fields.many2one(
            'hr.schedule.template',
            'Current Template',
            readonly=True,
        ),
        'st_new_id':
        fields.many2one(
            'hr.schedule.template',
            'New Template',
        ),
        'permanent':
        fields.boolean('Make Permanent', ),
        'temp_restday':
        fields.boolean(
            'Temporary Rest Day Change',
            help="If selected, change the rest day to the specified day only "
            "for the selected schedule.",
        ),
        'dayofweek':
        fields.selection(
            [('0', 'Monday'), ('1', 'Tuesday'), ('2', 'Wednesday'),
             ('3', 'Thursday'), ('4', 'Friday'), ('5', 'Saturday'),
             ('6', 'Sunday')],
            'Rest Day',
            select=True,
        ),
        'temp_week_start':
        fields.date('Start of Week', ),
        'week_start':
        fields.date('Start of Week', ),
    }

    _defaults = {
        'temp_restday': False,
    }

    def onchange_employee(self, cr, uid, ids, ee_id, context=None):

        res = {'value': {'st_current_id': False}}
        if ee_id:
            ee = self.pool.get('hr.employee').browse(cr,
                                                     uid,
                                                     ee_id,
                                                     context=None)
            res['value'][
                'st_current_id'] = ee.contract_id.schedule_template_id.id

        return res

    def onchange_week(self, cr, uid, ids, newdate):

        res = {'value': {'week_start': newdate}}
        if newdate:
            d = datetime.strptime(newdate, "%Y-%m-%d")
            if d.weekday() != 0:
                res['value']['week_start'] = False
                return res
        return res

    def onchange_temp_week(self, cr, uid, ids, newdate):

        res = {'value': {'temp_week_start': newdate}}
        if newdate:
            d = datetime.strptime(newdate, "%Y-%m-%d")
            if d.weekday() != 0:
                res['value']['temp_week_start'] = False
                return res
        return res

    def _create_detail(self,
                       cr,
                       uid,
                       schedule,
                       actual_dayofweek,
                       template_dayofweek,
                       week_start,
                       context=None):

        # First, see if there's a schedule for the actual dayofweek.
        # If so, use it.
        #
        for worktime in schedule.template_id.worktime_ids:
            if worktime.dayofweek == actual_dayofweek:
                template_dayofweek = actual_dayofweek

        prevutcdtStart = False
        prevDayofWeek = False
        user = self.pool.get('res.users').browse(cr, uid, uid, context=context)
        local_tz = timezone(user.tz)
        dSchedStart = datetime.strptime(schedule.date_start, OE_DFORMAT).date()
        dWeekStart = schedule.date_start < week_start and datetime.strptime(
            week_start, OE_DFORMAT).date() or dSchedStart

        for worktime in schedule.template_id.worktime_ids:

            if worktime.dayofweek != template_dayofweek:
                continue

            hour, sep, minute = worktime.hour_from.partition(':')
            toHour, toSep, toMin = worktime.hour_to.partition(':')
            if len(sep) == 0 or len(toSep) == 0:
                raise models.except_orm(
                    _('Invalid Time Format'),
                    _('The time should be entered as HH:MM'))

            # TODO - Someone affected by DST should fix this
            #
            dtStart = datetime.strptime(
                dWeekStart.strftime('%Y-%m-%d') + ' ' + hour + ':' + minute +
                ':00', '%Y-%m-%d %H:%M:%S')
            locldtStart = local_tz.localize(dtStart, is_dst=False)
            utcdtStart = locldtStart.astimezone(utc)
            if actual_dayofweek != '0':
                utcdtStart = utcdtStart + \
                    relativedelta(days=+int(actual_dayofweek))
            dDay = utcdtStart.astimezone(local_tz).date()

            # If this worktime is a continuation (i.e - after lunch) set the
            # start time based on the difference from the previous record
            #
            if prevDayofWeek and prevDayofWeek == actual_dayofweek:
                prevHour = prevutcdtStart.strftime('%H')
                prevMin = prevutcdtStart.strftime('%M')
                curHour = utcdtStart.strftime('%H')
                curMin = utcdtStart.strftime('%M')
                delta_seconds = (
                    datetime.strptime(curHour + ':' + curMin, '%H:%M') -
                    datetime.strptime(prevHour + ':' + prevMin,
                                      '%H:%M')).seconds
                utcdtStart = prevutcdtStart + timedelta(seconds=+delta_seconds)
                dDay = prevutcdtStart.astimezone(local_tz).date()

            delta_seconds = (
                datetime.strptime(toHour + ':' + toMin, '%H:%M') -
                datetime.strptime(hour + ':' + minute, '%H:%M')).seconds
            utcdtEnd = utcdtStart + timedelta(seconds=+delta_seconds)

            val = {
                'name': schedule.name,
                'dayofweek': actual_dayofweek,
                'day': dDay,
                'date_start': utcdtStart.strftime('%Y-%m-%d %H:%M:%S'),
                'date_end': utcdtEnd.strftime('%Y-%m-%d %H:%M:%S'),
                'schedule_id': schedule.id,
            }
            self.pool.get('hr.schedule').write(cr,
                                               uid,
                                               schedule.id, {
                                                   'detail_ids': [(0, 0, val)],
                                               },
                                               context=context)

            prevDayofWeek = worktime.dayofweek
            prevutcdtStart = utcdtStart

    def _change_restday(self,
                        cr,
                        uid,
                        employee_id,
                        week_start,
                        dayofweek,
                        context=None):

        sched_obj = self.pool.get('hr.schedule')
        sched_detail_obj = self.pool.get('hr.schedule.detail')

        schedule_ids = sched_obj.search(cr,
                                        uid,
                                        [('employee_id', '=', employee_id),
                                         ('date_start', '<=', week_start),
                                         ('date_end', '>=', week_start),
                                         ('state', 'not in', ['locked'])],
                                        context=context)
        sched = sched_obj.browse(cr, uid, schedule_ids[0], context=context)
        dtFirstDay = datetime.strptime(sched.detail_ids[0].date_start,
                                       OE_DTFORMAT)
        date_start = (dtFirstDay.strftime(OE_DFORMAT) < week_start
                      and week_start + ' ' + dtFirstDay.strftime('%H:%M:%S')
                      or dtFirstDay.strftime(OE_DTFORMAT))
        dtNextWeek = datetime.strptime(date_start,
                                       OE_DTFORMAT) + relativedelta(weeks=+1)

        # First get the current rest days
        rest_days = sched_obj.get_rest_days_by_id(
            cr,
            uid,
            sched.id,
            dtFirstDay.strftime(OE_DFORMAT),
            context=context)

        # Next, remove the schedule detail for the new rest day
        for dtl in sched.detail_ids:
            if (dtl.date_start < week_start or datetime.strptime(
                    dtl.date_start, OE_DTFORMAT) >= dtNextWeek):
                continue
            if dtl.dayofweek == dayofweek:
                sched_detail_obj.unlink(cr, uid, dtl.id, context=context)

        # Enter the new rest day(s)
        #
        sched_obj = self.pool.get('hr.schedule')
        nrest_days = [dayofweek] + rest_days[1:]
        dSchedStart = datetime.strptime(sched.date_start, OE_DFORMAT).date()
        dWeekStart = sched.date_start < week_start and datetime.strptime(
            week_start, OE_DFORMAT).date() or dSchedStart
        if dWeekStart == dSchedStart:
            sched_obj.add_restdays(cr,
                                   uid,
                                   sched,
                                   'restday_ids1',
                                   rest_days=nrest_days,
                                   context=context)
        elif dWeekStart == dSchedStart + relativedelta(days=+7):
            sched_obj.add_restdays(cr,
                                   uid,
                                   sched,
                                   'restday_ids2',
                                   rest_days=nrest_days,
                                   context=context)
        elif dWeekStart == dSchedStart + relativedelta(days=+14):
            sched_obj.add_restdays(cr,
                                   uid,
                                   sched,
                                   'restday_ids3',
                                   rest_days=nrest_days,
                                   context=context)
        elif dWeekStart == dSchedStart + relativedelta(days=+21):
            sched_obj.add_restdays(cr,
                                   uid,
                                   sched,
                                   'restday_ids4',
                                   rest_days=nrest_days,
                                   context=context)
        elif dWeekStart == dSchedStart + relativedelta(days=+28):
            sched_obj.add_restdays(cr,
                                   uid,
                                   sched,
                                   'restday_ids5',
                                   rest_days=nrest_days,
                                   context=context)

        # Last, add a schedule detail for the first rest day in the week using
        # the template for the new (temp) rest day
        #
        if len(rest_days) > 0:
            self._create_detail(cr,
                                uid,
                                sched,
                                str(rest_days[0]),
                                dayofweek,
                                week_start,
                                context=context)

    def _remove_add_schedule(self,
                             cr,
                             uid,
                             schedule_id,
                             week_start,
                             tpl_id,
                             context=None):
        """Remove the current schedule and add a new one in its place
        according to the new template. If the week that the change
        starts in is not at the beginning of a schedule create two
        new schedules to accommodate the truncated old one and the
        partial new one.
        """

        sched_obj = self.pool.get('hr.schedule')
        sched = sched_obj.browse(cr, uid, schedule_id, context=context)

        vals2 = False
        vals1 = {
            'name': sched.name,
            'employee_id': sched.employee_id.id,
            'template_id': tpl_id,
            'date_start': sched.date_start,
            'date_end': sched.date_end,
        }

        if week_start > sched.date_start:
            dWeekStart = datetime.strptime(week_start, '%Y-%m-%d').date()
            start_day = dWeekStart.strftime('%Y-%m-%d')
            vals1['template_id'] = sched.template_id.id
            vals1['date_end'] = (dWeekStart +
                                 relativedelta(days=-1)).strftime('%Y-%m-%d')
            vals2 = {
                'name': (sched.employee_id.name + ': ' + start_day + ' Wk ' +
                         str(dWeekStart.isocalendar()[1])),
                'employee_id':
                sched.employee_id.id,
                'template_id':
                tpl_id,
                'date_start':
                start_day,
                'date_end':
                sched.date_end,
            }

        sched_obj.unlink(cr, uid, schedule_id, context=context)
        _l.warning('vals1: %s', vals1)
        sched_obj.create(cr, uid, vals1, context=context)
        if vals2:
            _l.warning('vals2: %s', vals2)
            sched_obj.create(cr, uid, vals2, context=context)

    def _change_by_template(self,
                            cr,
                            uid,
                            employee_id,
                            week_start,
                            new_template_id,
                            doall,
                            context=None):

        sched_obj = self.pool.get('hr.schedule')

        schedule_ids = sched_obj.search(cr,
                                        uid,
                                        [('employee_id', '=', employee_id),
                                         ('date_start', '<=', week_start),
                                         ('date_end', '>=', week_start),
                                         ('state', 'not in', ['locked'])],
                                        context=context)

        # Remove the current schedule and add a new one in its place according
        # to the new template
        #
        if len(schedule_ids) > 0:
            self._remove_add_schedule(cr,
                                      uid,
                                      schedule_ids[0],
                                      week_start,
                                      new_template_id,
                                      context=context)

        # Also, change all subsequent schedules if so directed
        if doall:
            ids = sched_obj.search(cr,
                                   uid, [('employee_id', '=', employee_id),
                                         ('date_start', '>', week_start),
                                         ('state', 'not in', ['locked'])],
                                   context=context)
            for i in ids:
                self._remove_add_schedule(cr, uid, i, week_start,
                                          new_template_id, context)

    def change_restday(self, cr, uid, ids, context=None):

        data = self.read(cr, uid, ids[0], [], context=context)

        # Change the rest day for only one schedule
        if (data.get('temp_restday') and data.get('dayofweek')
                and data.get('temp_week_start')):
            self._change_restday(cr,
                                 uid,
                                 data['employee_id'][0],
                                 data['temp_week_start'],
                                 data['dayofweek'],
                                 context=context)

        # Change entire week's schedule to the chosen schedule template
        if (not data.get('temp_restday') and data.get('st_new_id')
                and data.get('week_start')):

            if data.get('week_start', False):
                self._change_by_template(cr,
                                         uid,
                                         data['employee_id'][0],
                                         data['week_start'],
                                         data['st_new_id'][0],
                                         data.get('permanent', False),
                                         context=context)

            # If this change is permanent modify employee's contract to
            # reflect the new template
            #
            if data.get('permanent', False):
                self.pool.get('hr.contract').write(
                    cr,
                    uid,
                    data['contract_id'][0], {
                        'schedule_template_id': data['st_new_id'][0],
                    },
                    context=context)

        return {
            'name': 'Change Schedule Template',
            'view_type': 'form',
            'view_mode': 'form',
            'res_model': 'hr.restday.wizard',
            'type': 'ir.actions.act_window',
            'target': 'new',
            'context': context
        }
Пример #18
0
class account_move_line(osv.osv):
    _inherit = "account.move.line"

    @api.one
    @api.depends('credit', 'debit', 'tax_code_id')
    def _compute_tax_base_values_for_manual_journal_items(self):
        if self.tax_code_id:
            if self.tax_code_id.code in ('1', '6', '8'):
                self.mtd_tax_amount = (self.credit - self.debit)
            elif self.tax_code_id.code in ('2', '9', '7'):
                self.mtd_tax_amount = (self.debit - self.credit)
            elif self.tax_code_id.code == '4':
                self.mtd_tax_amount = (self.debit - self.credit)
                journal_entry_obj = self.env['account.move.line'].search([
                    ('move_id', '=', self.move_id.id)
                ])
                if journal_entry_obj:
                    for line in journal_entry_obj:
                        if line.tax_code_id.code == '2':
                            self.mtd_tax_amount = (self.credit - self.debit)
        else:
            self.mtd_tax_amount = 0.00

    _columns = {
        'vat':
        fields.boolean(string="VAT Posted", default=False, readonly=True),
        'vat_submission_id':
        fields.many2one('mtd_vat.vat_submission_logs',
                        string='VAT Submission Period'),
        'unique_number':
        fields.related('vat_submission_id',
                       'unique_number',
                       type='char',
                       string="HMRC Unique Number",
                       readonly=True),
        'mtd_tax_amount':
        fields.float(
            'Mtd Tax/Base Amount',
            compute="_compute_tax_base_values_for_manual_journal_items",
            digits=dp.get_precision('Account'),
            store=True)
    }

    # Override of the base function reconcile , removing the control for the account if is field reconciled checked or not
    def mtd_reconcile(self,
                      cr,
                      uid,
                      ids,
                      type='auto',
                      writeoff_acc_id=False,
                      writeoff_period_id=False,
                      writeoff_journal_id=False,
                      context=None):
        account_obj = self.pool.get('account.account')
        move_obj = self.pool.get('account.move')
        move_rec_obj = self.pool.get('account.move.reconcile')
        partner_obj = self.pool.get('res.partner')
        currency_obj = self.pool.get('res.currency')
        lines = self.browse(cr, uid, ids, context=context)
        unrec_lines = filter(lambda x: not x['reconcile_id'], lines)
        credit = debit = 0.0
        currency = 0.0
        account_id = False
        partner_id = False
        if context is None:
            context = {}
        company_list = []
        for line in lines:
            if company_list and not line.company_id.id in company_list:
                raise osv.except_osv(
                    _('Warning!'),
                    _('To reconcile the entries company should be the same for all entries.'
                      ))
            company_list.append(line.company_id.id)
        for line in unrec_lines:
            if line.state != 'valid':
                raise osv.except_osv(
                    _('Error!'),
                    _('Entry "%s" is not valid !') % line.name)
            credit += line['credit']
            debit += line['debit']
            currency += line['amount_currency'] or 0.0
            account_id = line['account_id']['id']
            partner_id = (line['partner_id']
                          and line['partner_id']['id']) or False
        writeoff = debit - credit

        # Ifdate_p in context => take this date
        if context.has_key('date_p') and context['date_p']:
            date = context['date_p']
        else:
            date = time.strftime('%Y-%m-%d')

        cr.execute('SELECT account_id, reconcile_id '\
                   'FROM account_move_line '\
                   'WHERE id IN %s '\
                   'GROUP BY account_id,reconcile_id',
                   (tuple(ids), ))
        r = cr.fetchall()
        #TODO: move this check to a constraint in the account_move_reconcile object
        if len(r) != 1:
            raise osv.except_osv(
                _('Error'),
                _('Entries are not of the same account or already reconciled ! '
                  ))
        if not unrec_lines:
            raise osv.except_osv(_('Error!'),
                                 _('Entry is already reconciled.'))
        account = account_obj.browse(cr, uid, account_id, context=context)
        if r[0][1] != None:
            raise osv.except_osv(_('Error!'),
                                 _('Some entries are already reconciled.'))

        if (not currency_obj.is_zero(cr, uid, account.company_id.currency_id, writeoff)) or \
           (account.currency_id and (not currency_obj.is_zero(cr, uid, account.currency_id, currency))):
            # DO NOT FORWARD PORT
            if not writeoff_acc_id:
                if writeoff > 0:
                    writeoff_acc_id = account.company_id.expense_currency_exchange_account_id.id
                else:
                    writeoff_acc_id = account.company_id.income_currency_exchange_account_id.id
            if not writeoff_acc_id:
                raise osv.except_osv(
                    _('Warning!'),
                    _('You have to provide an account for the write off/exchange difference entry.'
                      ))
            if writeoff > 0:
                debit = writeoff
                credit = 0.0
                self_credit = writeoff
                self_debit = 0.0
            else:
                debit = 0.0
                credit = -writeoff
                self_credit = 0.0
                self_debit = -writeoff
            # If comment exist in context, take it
            if 'comment' in context and context['comment']:
                libelle = context['comment']
            else:
                libelle = _('Write-Off')

            cur_obj = self.pool.get('res.currency')
            cur_id = False
            amount_currency_writeoff = 0.0
            if context.get('company_currency_id', False) != context.get(
                    'currency_id', False):
                cur_id = context.get('currency_id', False)
                for line in unrec_lines:
                    if line.currency_id and line.currency_id.id == context.get(
                            'currency_id', False):
                        amount_currency_writeoff += line.amount_currency
                    else:
                        tmp_amount = cur_obj.compute(
                            cr,
                            uid,
                            line.account_id.company_id.currency_id.id,
                            context.get('currency_id', False),
                            abs(line.debit - line.credit),
                            context={'date': line.date})
                        amount_currency_writeoff += (
                            line.debit > 0) and tmp_amount or -tmp_amount

            writeoff_lines = [
                (0, 0, {
                    'name':
                    libelle,
                    'debit':
                    self_debit,
                    'credit':
                    self_credit,
                    'account_id':
                    account_id,
                    'date':
                    date,
                    'partner_id':
                    partner_id,
                    'currency_id':
                    cur_id or (account.currency_id.id or False),
                    'amount_currency':
                    amount_currency_writeoff and -1 * amount_currency_writeoff
                    or (account.currency_id.id and -1 * currency or 0.0)
                }),
                (0, 0, {
                    'name':
                    libelle,
                    'debit':
                    debit,
                    'credit':
                    credit,
                    'account_id':
                    writeoff_acc_id,
                    'analytic_account_id':
                    context.get('analytic_id', False),
                    'date':
                    date,
                    'partner_id':
                    partner_id,
                    'currency_id':
                    cur_id or (account.currency_id.id or False),
                    'amount_currency':
                    amount_currency_writeoff and amount_currency_writeoff
                    or (account.currency_id.id and currency or 0.0)
                })
            ]
            # DO NOT FORWARD PORT
            # In some exceptional situations (partial payment from a bank statement in foreign
            # currency), a write-off can be introduced at the very last moment due to currency
            # conversion. We record it on the bank statement account move.
            if context.get('bs_move_id'):
                writeoff_move_id = context['bs_move_id']
                for l in writeoff_lines:
                    self.create(cr, uid, dict(l[2], move_id=writeoff_move_id),
                                dict(context, novalidate=True))
                if not move_obj.validate(
                        cr, uid, writeoff_move_id, context=context):
                    raise osv.except_osv(
                        _('Error!'),
                        _('You cannot validate a non-balanced entry.'))
            else:
                writeoff_move_id = move_obj.create(
                    cr, uid, {
                        'period_id': writeoff_period_id,
                        'journal_id': writeoff_journal_id,
                        'date': date,
                        'state': 'draft',
                        'line_id': writeoff_lines
                    })

            writeoff_line_ids = self.search(
                cr, uid, [('move_id', '=', writeoff_move_id),
                          ('account_id', '=', account_id)])
            if account_id == writeoff_acc_id:
                writeoff_line_ids = [writeoff_line_ids[1]]
            ids += writeoff_line_ids

        # marking the lines as reconciled does not change their validity, so there is no need
        # to revalidate their moves completely.
        reconcile_context = dict(context, novalidate=True)
        r_id = move_rec_obj.create(cr,
                                   uid, {'type': type},
                                   context=reconcile_context)
        self.write(cr,
                   uid,
                   ids, {
                       'reconcile_id': r_id,
                       'reconcile_partial_id': False
                   },
                   context=reconcile_context)

        # the id of the move.reconcile is written in the move.line (self) by the create method above
        # because of the way the line_id are defined: (4, x, False)
        for id in ids:
            workflow.trg_trigger(uid, 'account.move.line', id, cr)

        if lines and lines[0]:
            partner_id = lines[0].partner_id and lines[0].partner_id.id or False
            if partner_id and not partner_obj.has_something_to_reconcile(
                    cr, uid, partner_id, context=context):
                partner_obj.mark_as_reconciled(cr,
                                               uid, [partner_id],
                                               context=context)
        return r_id