class ManufacturingOrderPlanningImproved(models.Model): _inherit = 'mrp.production' date_planned = fields.Datetime(readonly=False, states={ 'done': [('readonly', True)], 'cancel': [('readonly', True)] }) date_required = fields.Datetime(string="Date required", states={ 'done': [('readonly', True)], 'cancel': [('readonly', True)] }) taken_into_account = fields.Boolean( string="Taken into account", help="True if the manufacturing order has been taken into account", states={ 'done': [('readonly', True)], 'cancel': [('readonly', True)] }) final_order_id = fields.Many2one( 'mrp.production', string="Top parent order", help= "Final parent order in the chain of raw materials and produced products", compute='_compute_final_order_id') @api.multi def _compute_final_order_id(self): for rec in self: production = rec move = rec.move_created_ids and rec.move_created_ids[0] or False if move: while move.move_dest_id: move = move.move_dest_id if not move.move_dest_id and move.raw_material_production_id: production = move.raw_material_production_id move = move.raw_material_production_id.move_created_ids and \ move.raw_material_production_id.move_created_ids[0] or False rec.final_order_id = production @api.multi def _get_produce_line_data(self): self.ensure_one() move_vals = super(ManufacturingOrderPlanningImproved, self)._get_produce_line_data() date_move = fields.Datetime.to_string( self.location_dest_id.schedule_working_days( self.product_id.produce_delay + 1, fields.Datetime.from_string(self.date_planned))) move_vals['date_expected'] = date_move move_vals['date'] = date_move return move_vals @api.multi def get_date_expected_for_moves(self): self.ensure_one() days = self.product_id.produce_delay + 1 format_date_planned = fields.Datetime.from_string(self.date_planned) date_expected = self.location_dest_id.schedule_working_days( days, format_date_planned) return date_expected @api.multi def write(self, vals): result = super(ManufacturingOrderPlanningImproved, self).write(vals) if vals.get('date_planned'): for rec in self: # Add time if we get only date (e.g. if we have date widget on view) if not rec.taken_into_account: date_expected = rec.get_date_expected_for_moves() if date_expected: rec.move_created_ids.write({ 'date_expected': fields.Datetime.to_string(date_expected) }) return result @api.multi def action_reschedule(self): for rec in self: values = {} if rec.taken_into_account: values['date'] = min(rec.date_planned, rec.date_required) else: values['date'] = rec.date_required if self.env.context.get('reschedule_planned_date'): values['date_expected'] = rec.date_required rec.move_lines.write(values) @api.model def cron_recheck_availibility(self): orders = self.search([('state', 'in', ['confirmed', 'in_production'])]) orders.action_assign() chunk_number = 0 while orders: chunk_number += 1 chunk_orders = orders[:100] run_mrp_recheck_availability.delay( ConnectorSession.from_env(self.env), 'mrp.production', chunk_orders.ids, dict(self.env.context), description=u"MRP Recheck availability (chunk %s)" % chunk_number) orders -= chunk_orders
class grp_fondo_rotatorio_llavep(models.Model): _name = 'grp.fondo.rotatorio.llavep' def _check_linea_llavep_programa(self, cr, uid, ids): for llp in self.browse(cr, uid, ids): if llp.programa: if not llp.programa.isdigit(): return False return True def _check_linea_llavep_odg(self, cr, uid, ids): for llp in self.browse(cr, uid, ids): if llp.odg: if not llp.odg.isdigit(): return False return True def _check_linea_llavep_auxiliar(self, cr, uid, ids): for llp in self.browse(cr, uid, ids): if llp.auxiliar: if not llp.auxiliar.isdigit(): return False return True def _check_linea_llavep_disponible(self, cr, uid, ids): for llp in self.browse(cr, uid, ids): if llp.disponible: if not llp.disponible.isdigit(): return False return True def _check_linea_llavep_proyecto(self, cr, uid, ids): for llp in self.browse(cr, uid, ids): if llp.proyecto: if not llp.proyecto.isdigit(): return False return True def _check_linea_llavep_fin(self, cr, uid, ids): for llp in self.browse(cr, uid, ids): if llp.fin: if not llp.fin.isdigit(): return False return True def _check_linea_llavep_mon(self, cr, uid, ids): for llp in self.browse(cr, uid, ids): if llp.mon: if not llp.mon.isdigit(): return False return True def _check_linea_llavep_tc(self, cr, uid, ids): for llp in self.browse(cr, uid, ids): if llp.tc: if not llp.tc.isdigit(): return False return True fondo_rotatorios_llp_id = fields.Many2one('grp.fondo.rotatorio', string=u'3-1 Fondo Rotarorio', ondelete='cascade') #Campos de la estructura odg_id = fields.Many2one('grp.estruc_pres.odg', 'ODG', required=True) auxiliar_id = fields.Many2one('grp.estruc_pres.aux', 'Auxiliar', required=True, default=False) fin_id = fields.Many2one('grp.estruc_pres.ff', 'Fin') programa_id = fields.Many2one('grp.estruc_pres.programa', 'Programa') proyecto_id = fields.Many2one('grp.estruc_pres.proyecto', 'Proyecto') mon_id =fields.Many2one('grp.estruc_pres.moneda', 'Mon') tc_id = fields.Many2one('grp.estruc_pres.tc', 'TC') # Campos related fin = fields.Char(related='fin_id.ff',string='Fin related', store=True, readonly=True) programa = fields.Char(related='programa_id.programa', string='Programa related', store=True, readonly=True) proyecto = fields.Char(related='proyecto_id.proyecto', string='Proyecto related', store=True, readonly=True) odg = fields.Char(related='odg_id.odg', string='ODG related', store=True, readonly=True) auxiliar = fields.Char(related='auxiliar_id.aux', string='Auxiliar related', store=True, readonly=True) mon = fields.Char(related='mon_id.moneda', string='Mon related', store=True, readonly=True) tc = fields.Char(related='tc_id.tc', string='TC related', store=True, readonly=True) #montos disponible = fields.Char('Disponible', size=3) importe = fields.Integer('Importe') parent_state = fields.Selection(related='fondo_rotatorios_llp_id.state', readonly=True) # 001 - On_change llaves presupuestal def onchange_objeto_del_gasto(self, cr, uid, ids, odg_id, context=None): auxiliar_id = False if odg_id: auxiliar_ids = self.pool.get('grp.estruc_pres.aux').search(cr, uid, [('odg_id', '=', odg_id)]) if len(auxiliar_ids) == 1: auxiliar_id = auxiliar_ids[0] return {'value': { 'auxiliar_id': auxiliar_id, 'fin_id': False, 'programa_id': False, 'proyecto_id': False, 'mon_id': False, 'tc_id': False, }} def onchange_auxiliar(self, cr, uid, ids, auxiliar_id, context=None): fin_id = False if auxiliar_id: fin_ids = self.pool.get('grp.estruc_pres.ff').search(cr, uid, [('aux_id', '=', auxiliar_id)]) if len(fin_ids) == 1: fin_id = fin_ids[0] return {'value': { 'fin_id': fin_id, 'programa_id': False, 'proyecto_id': False, 'mon_id': False, 'tc_id': False }} def onchange_fuente_de_financiamiento(self, cr, uid, ids, fin_id, context=None): programa_id = False if fin_id: programa_ids = self.pool.get('grp.estruc_pres.programa').search(cr, uid, [('ff_id', '=', fin_id)]) if len(programa_ids) == 1: programa_id = programa_ids[0] return {'value': { 'programa_id': programa_id, 'proyecto_id': False, 'mon_id': False, 'tc_id': False, }} def onchange_programa(self, cr, uid, ids, programa_id, context=None): proyecto_id = False if programa_id: proyecto_ids = self.pool.get('grp.estruc_pres.proyecto').search(cr, uid,[('programa_id', '=', programa_id)]) if len(proyecto_ids) == 1: proyecto_id = proyecto_ids[0] return {'value': { 'proyecto_id': proyecto_id, 'mon_id': False, 'tc_id': False, }} def onchange_proyecto(self, cr, uid, ids, proyecto_id, context=None): mon_id = False if proyecto_id: mon_ids = self.pool.get('grp.estruc_pres.moneda').search(cr, uid, [('proyecto_id', '=', proyecto_id)]) if len(mon_ids) == 1: mon_id = mon_ids[0] return {'value': { 'mon_id': mon_id, 'tc_id': False, }} def onchange_moneda(self, cr, uid, ids, mon_id, context=None): tc_id = False if mon_id: tc_ids = self.pool.get('grp.estruc_pres.tc').search(cr, uid, [('moneda_id', '=', mon_id)]) if len(tc_ids) == 1: tc_id = tc_ids[0] return {'value': { 'tc_id': tc_id }} def _check_llavep_unica(self, cr, uid, ids, context=None): for line in self.browse(cr, uid, ids, context=context): lineas_duplicadas = self.search(cr, uid, [('fondo_rotatorios_llp_id', '=', line.fondo_rotatorios_llp_id.id), ('fin_id', '=', line.fin_id.id), ('programa_id', '=', line.programa_id.id), ('proyecto_id', '=', line.proyecto_id.id), ('odg_id', '=', line.odg_id.id), ('auxiliar_id', '=', line.auxiliar_id.id), ('mon_id', '=', line.mon_id.id), ('tc_id', '=', line.tc_id.id), ('id', 'not in', ids) ], context=context) if lineas_duplicadas: raise exceptions.ValidationError(_(u'No se pueden ingresar 2 líneas iguales para el mismo registro.')) return True _constraints = [ (_check_llavep_unica, u'Línea duplicada', ['fondo_rotatorios_llp_id', 'fin_id', 'programa_id', 'proyecto_id', 'odg_id', 'auxiliar_id' 'mon_id', 'tc_id']), (_check_linea_llavep_programa, u'Campo no es numérico', ['programa']), (_check_linea_llavep_odg, u'Campo no es numérico', ['odg']), (_check_linea_llavep_auxiliar, u'Campo no es numérico', ['auxiliar']), (_check_linea_llavep_disponible, u'Campo no es numérico', ['disponible']), # incidencias (_check_linea_llavep_proyecto, u'Campo no es numérico', ['proyecto']), (_check_linea_llavep_fin, u'Campo no es numérico', ['fin']), (_check_linea_llavep_mon, u'Campo no es numérico', ['mon']), (_check_linea_llavep_tc, u'Campo no es numérico', ['tc']), ]
class StockPicking(models.Model): _inherit = 'stock.picking' # Column Section is_expense_transfer = fields.Boolean( string='Is Expense Transfer', related='picking_type_id.is_expense_transfer', store=True) inventory_value = fields.Float(string='Inventory Value', compute='_compute_inventory_value', store=True) expense_transfer_move_id = fields.Many2one( comodel_name='account.move', string='Expense Transfer Accounting Entry', readonly=True, copy=False) # Compute Section @api.multi @api.depends('move_lines_related.inventory_value') def _compute_inventory_value(self): for picking in self: picking.inventory_value =\ sum(picking.mapped('move_lines_related.inventory_value')) # Custom Section @api.model def get_expense_entry_key(self, picking): """ define how to group by picking to generate a unique Journal Entry. By default, an entry is generated by picking type and by month. Overwrite this function to change the behaviour. """ dt = fields.Date.from_string(picking.date) return ( picking.picking_type_id.id, '%d-%d' % (dt.year, dt.month), ) @api.multi def generate_expense_entry(self): account_move_obj = self.env['account.move'] picking_data = {} for picking in self: key = self.get_expense_entry_key(picking) if key in picking_data.keys(): picking_data[key]['picking_ids'].append(picking.id) picking_data[key]['date'] = max(picking_data[key]['date'], picking.min_date) picking_data[key]['amount'] += picking.inventory_value else: picking_data[key] = { 'picking_type': picking.picking_type_id, 'picking_ids': [picking.id], 'date': picking.min_date, 'amount': picking.inventory_value, } for key, value in picking_data.iteritems(): pickings = self.browse(value['picking_ids']) picking_type = value['picking_type'] line_data = {} for picking in pickings: for move in picking.move_lines_related: account_id = move.product_id.product_tmpl_id.\ get_product_accounts()['expense'] if account_id in line_data: line_data[account_id] += move.inventory_value else: line_data[account_id] = move.inventory_value # Create Main Account Move Line line_values = { 'name': _('Expense Transfert (%s)') % (picking_type.name), 'date': value['date'], 'account_id': picking_type.expense_transfer_account_id.id, 'debit': (value['amount'] >= 0) and value['amount'] or 0, 'credit': (value['amount'] < 0) and -value['amount'] or 0, } account_move_lines = [(0, 0, line_values)] # Create Counterpart Account Move Line(s) for account_id, inventory_value in line_data.iteritems(): line_values = { 'name': _('Expense Transfert (%s)') % (picking_type.name), 'date': value['date'], 'product_id': False, 'product_uom_id': False, 'quantity': 0, 'account_id': account_id.id, 'credit': (inventory_value >= 0) and inventory_value or 0, 'debit': (inventory_value < 0) and -inventory_value or 0, } account_move_lines.append((0, 0, line_values)) # Generate Account Move move_values = { 'journal_id': picking_type.expense_transfer_journal_id.id, 'company_id': picking_type.warehouse_id.company_id.id, 'line_ids': account_move_lines, 'date': value['date'], 'ref': _('Expense Transfert (%s)') % (picking_type.name), } account_move_id = account_move_obj.create(move_values) # Validate Account Move account_move_id.post() # associate pickings to account move pickings.write({'expense_transfer_move_id': account_move_id.id})
class ebics_config(models.Model): ################################################### ################# LOGGER API STUB ################# ################################################### def logMessage(self, level, title, string): print level, title, string[:1500] self.env['l10n_fr_ebics.ebics_log'].create({ 'name': title, 'level': level, 'content': string, 'ebics_config_id': self.id }) ################################################### ################# STORAGE API STUB ################ ################################################### def getStatus(self): res = self.read(["status"])[0]["status"] return res def setStatus(self, status): self.write({'status': status}) def getBankAuthKeyHash(self): return str(self.bank_auth_key_certificate_hash) def getBankEncryptKeyHash(self): return str(self.bank_encrypt_key_certificate_hash) def saveLetter(self, letter, letterType): self.write({letterType: letter.encode('base64')}) def saveBankKey(self, keyType, keyVersion, modulus, public_exponent, certificate): self.write({ 'bank_' + keyType + '_key_certificate': certificate, 'bank_' + keyType + '_key_modulus': str(long(binascii.hexlify(modulus), 16)), 'bank_' + keyType + '_key_public_exponent': str(int(public_exponent, 16)), 'bank_' + keyType + '_key_version': keyVersion }) def savePartnerKey(self, keyType, keyVersion, modulus, private_exponent, public_exponent, certificate): self.write({ "partner_" + keyType + "_key_certificate": certificate, 'partner_' + keyType + '_key_modulus': str(modulus), 'partner_' + keyType + '_key_public_exponent': str(public_exponent), 'partner_' + keyType + '_key_private_exponent': str(private_exponent), 'partner_' + keyType + '_key_version': keyVersion }) def getPartnerKeyComponent(self, keyComponent, keyType): targetField = 'partner_' + keyType + '_key_' + keyComponent res = self.read([targetField])[0][targetField] return long(res) def getBankKeyComponent(self, keyComponent, keyType): targetField = 'bank_' + keyType + '_key_' + keyComponent res = self.read([targetField])[0][targetField] return long(res) def getPartnerCertificate(self, certificateType): targetField = 'partner_' + certificateType + '_key_certificate' return str(self.read([targetField])[0][targetField]) ################################################### ############### ODOO OBJECT FUNCTIONS ############# ################################################### def init_connexion(self): bank = Bank(self, str(self.bank_name), str(self.bank_host), str(self.bank_port), str(self.bank_root), str(self.bank_host_id)) partner = Partner(self, str(self.company_id.name), str(self.partner_id), str(self.user_id), self) partner.loadPartnerKeys() partner.loadBankKeys(bank) print "========== PARTNER KEYS AND CERTIFICATES LOADED ==========" print "========== BANK KEYS AND CERTIFICATES LOADED ==========" return partner, bank def hook_pre_send_file(self, partner, bank, dic): #fileUpload_from_fileSystem(partner, bank, "/home/yuntux/helloWorld.mp3","pain.xxx.cfonb160.dct", "fileName", True) fileUpload_from_fileSystem(partner, bank, "/home/yuntux/helloWorld.txt", "pain.xxx.cfonb160.dct", "fileName", True) def hook_post_get_file(self, partner, bank, dic): fileDownload_to_fileSystem(partner, bank, "/home/yuntux/") @api.one def send_file(self): partner, bank = self.init_connexion() self.hook_pre_send_file(partner, bank, None) @api.one def get_file(self): partner, bank = self.init_connexion() self.hook_post_get_file(partner, bank, None) @api.one def send_partner_keys(self): bank = Bank(self, str(self.bank_name), str(self.bank_host), str(self.bank_port), str(self.bank_root), str(self.bank_host_id)) partner = Partner(self, str(self.company_id.name), str(self.partner_id), str(self.user_id), self) partner.createPartnerKeys() print "========== PARTNER KEY GENERATION OK ==========" partner.handle_ini_exchange(bank) print "========== INI MESSAGE SENT ==========" print "========== WE HAVE NOW TO SEND THE HIA MESSAGE ==========" partner.handle_hia_exchange(bank) print "========== HIA MESSAGE SENT ==========" print "===>>> YOU HAVE TO SEND INITIATION LETTERS TO YOUR BANK BEFORE DOWNLOADING THE BANK KEYS" self.setStatus("bank_init") @api.one def get_bank_keys(self): bank = Bank(self, str(self.bank_name), str(self.bank_host), str(self.bank_port), str(self.bank_root), str(self.bank_host_id)) partner = Partner(self, str(self.company_id.name), str(self.partner_id), str(self.user_id), self) partner.loadPartnerKeys() bank_auth_key_hash = partner.storageService.getBankAuthKeyHash() bank_encrypt_key_hash = partner.storageService.getBankEncryptKeyHash() hpb_exchange(partner, bank, bank_auth_key_hash, bank_encrypt_key_hash) self.setStatus("ready") _name = 'l10n_fr_ebics.ebics_config' name = fields.Char() status = fields.Selection([('partner_init', 'Partner init'), ('bank_init', 'Bank init'), ('ready', 'Ready'), ('suspended', 'Suspended')], required=True, default="partner_init") company_id = fields.Many2one("res.company", string="Partner company", required=True) bank_name = fields.Char(required=True) bank_host = fields.Char(required=True) bank_port = fields.Integer(required=True) bank_root = fields.Text(required=True) bank_host_id = fields.Char(required=True) partner_id = fields.Char(required=True) user_id = fields.Char(required=True) #should be a many2one ebics_profile = fields.Selection([('t', 'EBICS T'), ('ts', 'EBICS TS')]) ebics_country = fields.Selection([('fr', 'France'), ('ch', 'Suisse')]) ebics_version = fields.Selection([('h003', 'H003'), ('h004', 'H004')]) ebics_revision = fields.Selection([('1', '1')]) ebics_specification = fields.Selection([('25', 'v2.5')]) bank_auth_key_certificate = fields.Text() bank_auth_key_certificate_hash = fields.Char( required=True) #should'nt be stored, just checked and forget after HPB bank_auth_key_modulus = fields.Text() bank_auth_key_public_exponent = fields.Text() bank_auth_key_version = fields.Char() bank_encrypt_key_certificate = fields.Text() bank_encrypt_key_certificate_hash = fields.Char( required=True) #should'nt be stored, just checked and forget after HPB bank_encrypt_key_modulus = fields.Text() bank_encrypt_key_public_exponent = fields.Text() bank_encrypt_key_version = fields.Char() partner_auth_key_certificate = fields.Text() partner_auth_key_certificate_hash = fields.Char( ) #should'nt be stored, just checked and forget after HPB partner_auth_key_modulus = fields.Text() partner_auth_key_public_exponent = fields.Text() partner_auth_key_private_exponent = fields.Text() partner_auth_key_version = fields.Char() partner_encrypt_key_certificate = fields.Text() partner_encrypt_key_certificate_hash = fields.Char( ) #should'nt be stored, just checked and forget after HPB partner_encrypt_key_modulus = fields.Text() partner_encrypt_key_public_exponent = fields.Text() partner_encrypt_key_private_exponent = fields.Text() partner_encrypt_key_version = fields.Char() partner_sign_key_certificate = fields.Text() partner_sign_key_certificate_hash = fields.Char( ) #should'nt be stored, just checked and forget after HPB partner_sign_key_modulus = fields.Text() partner_sign_key_public_exponent = fields.Text() partner_sign_key_private_exponent = fields.Text() partner_sign_key_version = fields.Char() ini_letter_sign = fields.Binary() hia_letter_encrypt = fields.Binary() hia_letter_auth = fields.Binary() ebics_log_ids = fields.One2many('l10n_fr_ebics.ebics_log', 'ebics_config_id')
class restaurant_table(models.Model): _inherit = "restaurant.table" floor_id = fields.Many2one('restaurant.floor', 'Floor')
class AccountMoveLine(models.Model): _inherit = "account.move.line" check_deposit_id = fields.Many2one('account.check.deposit', string='Check Deposit', copy=False)
class ResConfig(models.TransientModel): _name = "hr.training.config.setting" _inherit = "res.config.settings" @api.model def _default_company_id(self): return self.env.user.company_id.id company_id = fields.Many2one( string="Company", comodel_name="res.company", required=True, default=lambda self: self._default_company_id(), ) employee_training_allowed_confirm_group_ids = fields.Many2many( string="Allowed Confirm Employee Training", comodel_name="res.groups", relation="rel_company_emp_training_allowed_confirm", column1="company_id", column2="group_id", related="company_id.employee_training_allowed_confirm_group_ids", ) employee_training_allowed_approve_group_ids = fields.Many2many( string="Allowed Approve Employee Training", comodel_name="res.groups", relation="rel_company_emp_training_allowed_approve", column1="company_id", column2="group_id", related="company_id.employee_training_allowed_approve_group_ids", ) employee_training_allowed_start_group_ids = fields.Many2many( string="Allowed Start Employee Training", comodel_name="res.groups", relation="rel_company_emp_training_allowed_start", column1="company_id", column2="group_id", related="company_id.employee_training_allowed_start_group_ids", ) employee_training_allowed_finish_group_ids = fields.Many2many( string="Allowed Finish Employee Training", comodel_name="res.groups", relation="rel_company_emp_training_allowed_finish", column1="company_id", column2="group_id", related="company_id.employee_training_allowed_finish_group_ids", ) employee_training_allowed_cancel_group_ids = fields.Many2many( string="Allowed Cancel Employee Training", comodel_name="res.groups", relation="rel_company_emp_training_allowed_cancel", column1="company_id", column2="group_id", related="company_id.employee_training_allowed_cancel_group_ids", ) employee_training_allowed_restart_group_ids = fields.Many2many( string="Allowed Restart Employee Training", comodel_name="res.groups", relation="rel_company_emp_training_allowed_restart", column1="company_id", column2="group_id", related="company_id.employee_training_allowed_restart_group_ids", ) module_hr_employee_training_allowance = fields.Boolean( string="Manage Training Allowance", ) module_hr_employee_training_budget = fields.Boolean( string="Manage Training Budget", ) module_hr_employee_training_evaluation = fields.Boolean( string="Manage Training Evaluation", ) module_hr_employee_training_experience = fields.Boolean( string="Experience", ) module_hr_employee_training_analytic = fields.Boolean( string="Analytic Account", ) module_hr_employee_training_job_family_modelling = fields.Boolean( string="Job Family Modelling", ) module_hr_employee_training_organization_unit = fields.Boolean( string="Organization Unit", )
class ir_attachment(models.Model): _inherit = 'ir.attachment' # Dummy field to search attachments of a travel request. # No need to store this field because we already have two fields # res_model and res_id. travel_request_id = fields.Many2one(comodel_name='hr.travel.request', string='Travel Request', compute=lambda *a: False, store=False) @api.model def create(self, vals): """ When a document of a travel request is attached, increase a counting field of documents of that travel request. """ attachment = super(ir_attachment, self).create(vals) if vals.get('res_model', '') == 'hr.travel.request'\ and vals.get('res_id', False): model_obj = self.env['hr.travel.request'] model = model_obj.browse(vals['res_id']) model.attachments_count = model.attachments_count + 1 return attachment @api.multi def unlink(self): """ When a document of a travel request is removed, decrease a counting field of documents of that travel request. """ request_ids = [] for attachment in self: if attachment.res_model == 'hr.travel.request'\ and attachment.res_id: request_ids.append(attachment.res_id) res = super(ir_attachment, self).unlink() if not request_ids: return res request_obj = self.env['hr.travel.request'] for request in request_obj.browse(request_ids): request.attachments_count = request.attachments_count - 1 return res @api.model @api.returns('self') def search(self, args, offset=0, limit=None, order=None, count=False): """ Search documents by travel request. """ new_args = [] for domain in args: if isinstance(domain, (list, tuple))\ and domain[0] == 'travel_request_id': request_obj = self.env['hr.travel.request'] requests = request_obj.search([('name', 'ilike', domain[2])]) if not requests: continue new_args += [('res_model', '=', 'hr.travel.request'), ('res_id', 'in', requests.ids)] else: new_args.append(domain) return super(ir_attachment, self).search(new_args, offset=offset, limit=limit, order=order, count=count)
class PurchaseOrder(models.Model): _inherit = 'purchase.order' origin = fields.Char(copy=True) requisition_id = fields.Many2one(copy=True)
class WebsiteSupportTicketMessage(models.Model): _name = "website.support.ticket.message" ticket_id = fields.Many2one('website.support.ticket', string='Ticket ID') content = fields.Text(string="Content")
class hr_payslip_run_extension(models.Model): _inherit = 'hr.payslip.run' date = fields.Date(string="Date") company_id = fields.Many2one( 'res.company', string="Company", default=lambda self: self.env['res.company']._company_default_get()) ### Customers Report @api.multi def hr_employee_report(self): # Column Headers if self.date: heading = "Salary Up-Load" company = self.company_id.name date = datetime.datetime.strptime( self.date, tools.DEFAULT_SERVER_DATE_FORMAT).strftime('%d-%b-%Y') date1 = datetime.datetime.strptime( self.date, tools.DEFAULT_SERVER_DATE_FORMAT) month = date1.strftime('%B') year = date1.strftime('%Y') file_name = "Salary Upload For %s %s" % (month, year) workbook = xlwt.Workbook() worksheet = workbook.add_sheet('Sheet 1') sp_style = xlwt.easyxf( 'font: bold on, height 200; borders: bottom thin, top thin, left thin, right thin' ) base_style = xlwt.easyxf( 'align: wrap 1; borders: bottom thin, top thin, left thin, right thin' ) worksheet.write_merge(0, 0, 0, 2, heading, sp_style) worksheet.write_merge(2, 2, 0, 0, "Company", sp_style) worksheet.write_merge(2, 2, 1, 4, company, sp_style) worksheet.write_merge(4, 4, 0, 0, "Date", sp_style) worksheet.write_merge(4, 4, 1, 1, date, sp_style) row_index = 6 headers = [ 'Sr. No', 'Employee Code', 'Account Number', 'Employee Name', 'Dr./Cr.', 'Amount', 'Narration' ] for index, value in enumerate(headers): worksheet.write(row_index, index, value, sp_style) worksheet.col(0).width = 3000 worksheet.col(1).width = 4000 worksheet.col(2).width = 5000 worksheet.col(3).width = 5000 worksheet.col(4).width = 2000 worksheet.col(5).width = 4000 worksheet.col(6).width = 6000 row_index += 1 narretion = "Salary For %s %s" % (month, year) sn = 1 for record in self.slip_ids: net = 0 for emp in record: for line in emp.line_ids: if line.code == "NET": net = line.amount worksheet.write(row_index, 0, str(sn), base_style) worksheet.write(row_index, 1, record.employee_id.id, base_style) worksheet.write(row_index, 2, record.employee_id.bank_account_id.acc_number, base_style) worksheet.write(row_index, 3, record.employee_id.name, base_style) worksheet.write(row_index, 4, 'Cr', base_style) worksheet.write(row_index, 5, net, base_style) worksheet.write(row_index, 6, narretion, base_style) sn += 1 row_index += 1 fp = StringIO() workbook.save(fp) fp.seek(0) data = fp.read() fp.close() encoded_data = base64.encodestring(data) local_tz = pytz.timezone(self._context.get('tz') or 'UTC') attach_vals = { 'name': '%s' % (file_name), 'datas': encoded_data, 'datas_fname': '%s.xls' % (file_name), 'res_model': 'hr.payslip.run', } doc_id = self.env['ir.attachment'].create(attach_vals) return { 'type': 'ir.actions.act_url', 'url': '/web/binary/download_document?model=%s&field=%s&id=%s&filename=%s.xls' % ('ir.attachment', 'datas', doc_id.id, doc_id.name), 'target': 'self', } else: raise UserError("Please Insert Date.")
class ProductDateSoldReturnedInvoices(models.Model): _name = 'product.date.sold.returned.invoices' _description = 'Sale Invoice Report' _auto = False shop_id = fields.Many2one('stock.warehouse','Shop') partner_id = fields.Many2one('res.partner', string='Client') user_id = fields.Many2one('res.users', string='Salesperson') date_invoice = fields.Date('Date Order') date_invoice_day = fields.Integer('Day') date_invoice_month = fields.Integer('Month') date_invoice_year = fields.Integer('Year') product_id = fields.Many2one('product.product', string='Product') categ_id = fields.Many2one('product.category', string='Product Category') inv_qty_sold = fields.Float('Quantity Sold') amount_sold = fields.Float('Amount Sold') amount_discounted = fields.Float('Amount Discounted') price_unit = fields.Float('Average Price Unit', group_operator="avg") inv_qty_returned = fields.Float('Quantity Returned') amount_returned = fields.Float('Amount Returned') num_invoices_sold = fields.Integer('Num Orders Sold') num_invoices_returned = fields.Integer('Num Orders Returned') def _select(self, select=False): if select: select_str= select else: select_str = """ SELECT shop_id, partner_id, user_id, date_invoice, extract(day from cast(date_invoice as timestamp)) as date_invoice_day, extract(month from cast(date_invoice as timestamp)) as date_invoice_month, extract(year from cast(date_invoice as timestamp)) as date_invoice_year, product_id, categ_id, sum(inv_qty_sold) as inv_qty_sold, sum(amount_sold) as amount_sold, sum(amount_discounted) as amount_discounted, avg(price_unit) as price_unit, sum(inv_qty_returned) as inv_qty_returned, sum(amount_returned) as amount_returned, sum(num_invoices_sold) as num_invoices_sold, sum(num_invoices_returned) as num_invoices_returned FROM ( SELECT date_invoice, partner_id, user_id, shop_id, product_id, sum(inv_qty_sold) as inv_qty_sold, sum(amount_sold) as amount_sold, sum(amount_discounted) as amount_discounted, avg(price_unit) as price_unit, sum(inv_qty_returned) as inv_qty_returned, sum(amount_returned) as amount_returned, count(invoice_id) as num_invoices_sold, 0.0 as num_invoices_returned FROM product_sale_invoice_list WHERE inv_qty_sold > 0 AND inv_qty_returned = 0 GROUP BY date_invoice, product_id, shop_id, partner_id, user_id UNION SELECT date_invoice, partner_id, user_id, shop_id, product_id, sum(inv_qty_sold) as inv_qty_sold, sum(amount_sold) as amount_sold, sum(amount_discounted) as amount_discounted, avg(price_unit) as price_unit, sum(inv_qty_returned) as inv_qty_returned, sum(amount_returned) as amount_returned, 0.0 as num_invoices_sold, count(invoice_id) as num_invoices_returned FROM product_sale_invoice_list WHERE inv_qty_sold = 0 AND inv_qty_returned > 0 GROUP BY date_invoice, product_id, shop_id, partner_id, user_id ) as total_sale_invoices LEFT JOIN product_product pp ON pp.id = product_id LEFT JOIN product_template pt ON pt.id = pp.product_tmpl_id GROUP BY date_invoice, product_id, categ_id, shop_id, partner_id, user_id ORDER BY date_invoice, product_id """ return select_str def init(self, cr, select=False, mlc=False, mlr=False): table = "product_date_sold_returned_invoices" cr.execute(""" SELECT table_type FROM information_schema.tables WHERE table_name = '%s'; """ % table) vista = cr.fetchall() for v in vista: if v[0] == 'VIEW': cr.execute(""" DROP VIEW IF EXISTS %s; """ % table); cr.execute(""" DROP MATERIALIZED VIEW IF EXISTS %s; CREATE MATERIALIZED VIEW %s as (( SELECT row_number() over() as id, * FROM (( %s )) as asd ))""" % (table, table, self._select(select))) def fields_view_get(self, cr, user, view_id=None, view_type='form', context=None, toolbar=False, submenu=False): if context is None: context = {} #Nos aseguramos que se actualice si o si al entrar, aunque alguno le mande algun valor por defecto al dominio if view_type=="tree": self.pool.get('m.report.view').check_and_refresh_materialized_view(cr, user, "product_sale_invoice_list") self.pool.get('m.report.view').check_and_refresh_materialized_view(cr, user, "product_date_sold_returned_invoices") res = super(ProductDateSoldReturnedInvoices, self).fields_view_get(cr, user, view_id, view_type, context, toolbar=toolbar, submenu=submenu) return res
class bsa_fnc(models.Model): _name = 'bsa.fnc' _inherit = ['mail.thread'] _order = 'name desc' name = fields.Char("N°", readonly=True) createur_id = fields.Many2one('res.users', 'Créateur', required=True) date_creation = fields.Date("Date de création", required=True) type_fnc = fields.Selection([ ('interne', 'Interne'), ('client', 'Client'), ('fournisseur', 'Fournisseur'), ('amelioration', 'Amélioration'), ], "Type", required=True) partner_id = fields.Many2one('res.partner', u'Partenaire', help='Client ou Fournisseur', required=True) ref_partenaire = fields.Char(u"Référence partenaire") categorie_id = fields.Many2one('bsa.fnc.categorie', u'Catégorie') product_id = fields.Many2one('product.product', u'Article') rsp_projet_id = fields.Many2one('res.users', u'Responsable de projet') date_projet = fields.Date(u"Date du projet") description = fields.Text(u"Description du problème") demande_bsa = fields.Text(u"Demande de BSA") action = fields.Text(u"Action immédiate") analyse = fields.Text(u"Analyse") resolution = fields.Text(u"Action corrective") date_reponse = fields.Date(u"Date de réponse") evaluation = fields.Text(u"Évaluation") date_evaluation = fields.Date(u"Date évaluation") evaluateur_id = fields.Many2one('res.users', u'Evaluateur') cout = fields.Integer(u"Avoir") attachment_ids = fields.Many2many('ir.attachment', 'bsa_fnc_attachment_rel', 'bsa_fnc_id', 'attachment_id', u'Pièces jointes') state = fields.Selection([ ('ouverte', 'Ouverte'), ('encours', 'En cours'), ('fermee', 'Fermée'), ], u"État") def _date_creation(): now = datetime.date.today() # Date du jour return now.strftime('%Y-%m-%d') # Formatage _defaults = { 'state': 'ouverte', 'date_creation': _date_creation(), 'createur_id': lambda obj, cr, uid, ctx=None: uid, } @api.model def create(self, vals): #** Numérotation ******************************************************* data_obj = self.env['ir.model.data'] sequence_ids = data_obj.search([('name', '=', 'bsa_fnc_seq')]) if sequence_ids: sequence_id = sequence_ids[0].res_id vals['name'] = self.env['ir.sequence'].get_id(sequence_id, 'id') obj = super(bsa_fnc, self).create(vals) #*********************************************************************** return obj @api.multi def action_send_mail(self): cr = self._cr uid = self._uid ids = self._ids for obj in self: ir_model_data = self.pool.get('ir.model.data') try: template_id = ir_model_data.get_object_reference( cr, uid, 'is_bsa', 'bsa_fnc_email_template4')[1] except ValueError: template_id = False try: compose_form_id = ir_model_data.get_object_reference( cr, uid, 'is_bsa', 'is_email_compose_message_wizard_form')[1] except ValueError: compose_form_id = False ctx = dict() attachment_ids = [] for attachment in obj.attachment_ids: attachment_ids.append(attachment.id) vals = {'attachment_ids': [(6, 0, attachment_ids)]} attachment_selection_ids = [] attachment_selection_ids.append(vals) ctx.update({ 'default_model': 'bsa.fnc', 'default_res_id': obj.id, 'default_use_template': bool(template_id), 'default_template_id': template_id, 'default_attachment_selection_ids': attachment_selection_ids, 'default_composition_mode': 'comment', 'mark_so_as_sent': True }) return { 'type': 'ir.actions.act_window', 'view_type': 'form', 'view_mode': 'form', 'res_model': 'mail.compose.message', 'views': [(compose_form_id, 'form')], 'view_id': compose_form_id, 'target': 'new', 'context': ctx, } def message_new(self, cr, uid, msg_dict, custom_values=None, context=None): """Méthode provenant par surcharge de mail.tread permettant de personnaliser la création de la fnc lors de la réception d'un mail avec le serveur de courrier entrant créé""" if context is None: context = {} data = {} if isinstance(custom_values, dict): data = custom_values.copy() model = context.get('thread_model') or self._name model_pool = self.pool[model] fields = model_pool.fields_get(cr, uid, context=context) if 'name' in fields and not data.get('name'): data['name'] = msg_dict.get('subject', '') ref_partenaire = msg_dict.get('email_from', '') description = '' if msg_dict.get('body'): html = msg_dict.get('body') description = html2text.html2text(html) # #print description # #print description.decode('utf-8') # #print description.decode('iso-8859-1') # #.decode('iso-8859-1').encode('utf8') # #description = unicodedata.normalize('NFKD', description).encode('ascii', 'ignore') # #description = description.decode('cp1252').encode('utf-8') # #description = description.decode('cp1252') # #description = description.decode('ascii') # #description = description.decode('iso8859_15') # #description = description.decode('utf-8') # #print type(description) # #description = description.decode('iso-8859-1').encode('utf8') # description = description.encode('utf-8') # temp.write(description) # temp.close() # tree = ET.parse(filename) # root = tree.getroot() # for n1 in root: # if n1.tag in fields: # #print n1.tag,' : ',n1.text.strip() # data[n1.tag] = n1.text.strip() # data['is_import_par_mail'] = True data['type_fnc'] = 'interne' data['partner_id'] = 1 data['ref_partenaire'] = ref_partenaire data['description'] = description res_id = model_pool.create(cr, uid, data, context=context) return res_id
class WizradInvoice(models.TransientModel): _inherit = "wizard.invoice" res_partner_id = fields.Many2one('res.partner',string='Partner') partner_id = fields.Many2one('res.partner',string='Partner') @api.model def default_get(self, fields): res = {} #THANH: set default journal from property property_obj = self.env['admin.property'].search([('name','=','wizard_invoice_default_journal')]) or None if property_obj: res.update({'journal_id':int(property_obj.value)}) vars=[] active_id = self._context.get('active_id') if active_id: si = self.env['sale.contract'].browse(active_id) res_partner_id = si.partner_id partner_id = self.env['res.partner'].search([('name','=','NEDCOFFEE BV')]) account_id = partner_id.property_account_payable_id.id or False nvs =si.name[4:len(si.name)] now = datetime.now() current_year = str(now.year) current_year = current_year[2:4] name ='INV-'+ str(current_year) +'-'+ nvs res.update({'partner_id':partner_id.id,'res_partner_id':res_partner_id.id,'account_id':account_id, 'contract_id': active_id, 'date': datetime.now().strftime(DEFAULT_SERVER_DATETIME_FORMAT) or False, 'currency_id': si.currency_id.id or False,'name':name}) for line in si.contract_line: vars.append((0, 0, {'product_id':line.product_id.id,'product_qty': line.product_qty or 0.0, 'price_unit': line.price_unit or 0.0})) res.update({'wizard_ids':vars}) return res @api.multi def create_invoice(self): active_id = self._context.get('active_id') invoice_pool = self.env['account.invoice'] invoice_line_pool = self.env['account.invoice.line'] si = self.env['sale.contract'].browse(active_id) partner_id = self.env['res.partner'].search([('name','=','NEDCOFFEE BV')]) account_id = partner_id.property_account_receivable_id.id or False payment_term = partner_id.property_payment_term_id.id or False # nvs =si.name[4:len(si.name)] # now = datetime.now() # current_year = now.year # # name ='INV-'+ str(current_year) +'.'+ nvs invoice_vals = {'partner_id':partner_id.id, 'name': self.name, 'origin': si.name, 'supplier_inv_date': False, 'res_partner_id': si.partner_id.id, 'reference': self.name, 'type': 'out_invoice', 'account_id': account_id, 'date_invoice': self.date or False, 'currency_id': self.currency_id.id or False, 'comment': '', 'company_id': 1, 'user_id': self.env.uid, 'journal_id': self.journal_id.id or False, 'payment_term_id': payment_term, 'fiscal_position_id': partner_id.property_account_position_id.id or False, 'sale_contract_id': si.id or False} invoice_id = invoice_pool.create(invoice_vals) for line in self.wizard_ids: vals = self._prepare_invoice_line( line, invoice_id, invoice_vals) invoice_line_pool.create(vals) invoice_id.compute_taxes() if invoice_id: imd = self.env['ir.model.data'] action = imd.xmlid_to_object('account.action_invoice_tree1') form_view_id = imd.xmlid_to_res_id('account.invoice_form') result = { 'name': action.name, 'help': action.help, 'type': action.type, 'views': [[form_view_id, 'form']], 'target': action.target, 'context': action.context, 'res_model': action.res_model, 'res_id': invoice_id.ids[0], 'views' : [(form_view_id, 'form')], } return result
class checkout_wizard(models.TransientModel): '''月末结账的向导''' _name = 'checkout.wizard' period_id = fields.Many2one('finance.period', u'结账会计期间', required=True) date = fields.Date(u'生成凭证日期') @api.multi @api.onchange('date') def onchange_period_id(self): self.period_id = self.env['finance.period'].get_period(self.date) @api.multi def button_checkout(self): if self.period_id: last_period = self.env[ 'create.trial.balance.wizard'].compute_last_period_id( self.period_id) if not last_period.is_closed: raise except_orm(u'错误', u'上一个期间%s未结账' % last_period.name) if self.period_id.is_closed: raise except_orm(u'错误', u'本期间已结账') voucher_obj = self.env['voucher'] voucher_ids = voucher_obj.search([('period_id', '=', self.period_id.id)]) i = 0 for voucher_id in voucher_ids: if voucher_id.state != 'done': i += 1 if i != 0: raise except_orm(u'错误', u'该期间有%s张凭证未审核' % i) else: voucher_line = [] #生成的结账凭证行 account_obj = self.env['finance.account'] company_obj = self.env['res.company'] voucher_line_obj = self.env['voucher.line'] revenue_account_ids = account_obj.search([('costs_types', '=', 'in')]) #收入类科目 expense_account_ids = account_obj.search([('costs_types', '=', 'out')]) #费用类科目 revenue_total = 0 #收入类科目合计 expense_total = 0 #费用类科目合计 for revenue_account_id in revenue_account_ids: voucher_line_ids = voucher_line_obj.search([ ('account_id', '=', revenue_account_id.id), ('voucher_id.period_id', '=', self.period_id.id) ]) credit_total = 0 for voucher_line_id in voucher_line_ids: credit_total += voucher_line_id.credit revenue_total += credit_total if credit_total != 0: res = { 'name': u'月末结账', 'account_id': revenue_account_id.id, 'debit': credit_total, 'credit': 0, } voucher_line.append(res) for expense_account_id in expense_account_ids: voucher_line_ids = voucher_line_obj.search([ ('account_id', '=', expense_account_id.id), ('voucher_id.period_id', '=', self.period_id.id) ]) debit_total = 0 for voucher_line_id in voucher_line_ids: debit_total += voucher_line_id.debit expense_total += debit_total if debit_total != 0: res = { 'name': u'月末结账', 'account_id': expense_account_id.id, 'debit': 0, 'credit': debit_total, } voucher_line.append(res) #利润结余 year_profit_account = company_obj.search([])[0].profit_account if (revenue_total - expense_total) > 0: res = { 'name': u'利润结余', 'account_id': year_profit_account.id, 'debit': 0, 'credit': revenue_total - expense_total, } voucher_line.append(res) if (revenue_total - expense_total) < 0: res = { 'name': u'利润结余', 'account_id': year_profit_account.id, 'debit': expense_total - revenue_total, 'credit': 0, } voucher_line.append(res) #生成凭证 valus = { 'is_checkout': True, 'date': self.date, 'line_ids': [(0, 0, line) for line in voucher_line], } voucher = voucher_obj.create(valus) voucher.voucher_done() if self.period_id.month == '12': year_profit_ids = voucher_line_obj.search([ ('account_id', '=', year_profit_account.id), ('voucher_id.period_id', '=', self.period_id.id) ]) year_total = 0 for year_profit_id in year_profit_ids: year_total += (year_profit_id.credit - year_profit_id.debit) year_line_ids = [{ 'name': u'年度结余', 'account_id': company_obj.search([])[0].no_profit_account.id, 'debit': 0, 'credit': year_total, }, { 'name': u'年度结余', 'account_id': year_profit_account.id, 'debit': year_total, 'credit': 0, }] value = { 'is_checkout': True, 'date': self.date, 'line_ids': [(0, 0, line) for line in year_line_ids], } year_account = voucher_obj.create(value) year_account.voucher_done() #关闭会计期间 self.period_id.is_closed = True #如果下一个会计期间没有,则创建。 next_period = self.env[ 'create.trial.balance.wizard'].compute_next_period_id( self.period_id) if not next_period: if self.period_id.month == '12': self.env['finance.period'].create({ 'year': self.period_id.year + 1, 'month': 1, }) else: self.env['finance.period'].create({ 'year': self.period_id.year, 'month': self.period_id.month + 1, }) #显示凭证 view = self.env.ref('finance.voucher_form') return { 'name': u'月末结账', 'view_type': 'form', 'view_mode': 'form', 'views': [(view.id, 'form')], 'res_model': 'voucher', 'type': 'ir.actions.act_window', 'res_id': voucher.id, 'limit': 300, } @api.multi def button_counter_checkout(self): if self.period_id: if not self.period_id.is_closed: raise except_orm(u'错误', u'本期间未结账') else: self.period_id.is_closed = False voucher_ids = self.env['voucher'].search([ ('is_checkout', '=', True), ('period_id', '=', self.period_id.id) ]) for voucher_id in voucher_ids: voucher_id.voucher_draft() voucher_id.unlink() return
class mrp_planning_mo_at_earlier(models.TransientModel): """ ManufacturingOrder Planning at earlier """ _name = 'mrp.planning.mo.at.earlier' _description = 'ManufacturingOrder Planning at earlier' _rec_name = 'mo_id' @api.model def default_get(self, fields_list): res = super(mrp_planning_mo_at_earlier, self).default_get(fields_list=fields_list) # Fonction permettant de passer par défaut l'id de l'OF ouvert if self.env.context.get('active_model') == 'mrp.simulation': mo = self.env['mrp.simulation'].browse(self.env.context.get('active_id')).mo_id else: mo = self.env['mrp.manufacturingorder'].browse(self.env.context.get('active_id')) res['mo_id'] = mo.id res['date'] = mo.min_start_date return res #=========================================================================== # COLUMNS #=========================================================================== date = fields.Datetime(string='Date', required=True) mo_id = fields.Many2one('mrp.manufacturingorder', string='Manufacturing Order', required=True, ondelete='cascade') is_procur_level_manufact = fields.Boolean(string='Procurement level', default=False) is_product_sublevel_manufact = fields.Boolean(string='Procurement Sublevel', default=False) is_procur_level_purchase = fields.Boolean(string='Procurement level', default=False) is_procur_sublevel_purchase = fields.Boolean(string='Procurement Sublevel', default=False) automatic_purchase = fields.Boolean(string='Generate Purchase', default=False) is_sublevel = fields.Boolean(string='Generate Full', default=False) change_resources = fields.Boolean(string='Load balancing', default=True) is_delay_rm = fields.Boolean(string='RM delay', default=False) is_from_simulation = fields.Boolean(default=False) #=========================================================================== # Boutons #=========================================================================== @api.multi def button_plannification_mo_at_earlier(self): """ Bouton qui plannifie l'OF au plus tôt """ wo_obj = self.env['mrp.workorder'] for wiz in self: date = wiz.date_plannif() wo_obj.plannification_mo_at_earlier(date, wiz.mo_id, is_sublevel=wiz.is_sublevel, is_procur_level_manufact=wiz.is_procur_level_manufact, is_product_sublevel_manufact=wiz.is_product_sublevel_manufact, is_procur_level_purchase=wiz.is_procur_level_purchase, automatic_purchase=wiz.automatic_purchase, is_procur_sublevel_purchase=wiz.is_procur_sublevel_purchase, first_mo_id=False, is_delay_rm=wiz.is_delay_rm, change_resources=wiz.change_resources, no_modif_prio_date=False) return True def date_plannif(self): """ Point d'entrée pour brightloop car eux on choisie d'avoir un champ date et de passer comme heure 12:00 """ return self.date #=========================================================================== # On Change #=========================================================================== @api.onchange('is_procur_level_manufact') def _onchange_is_procur_level_manufact(self): if not self.is_procur_level_manufact: self.is_product_sublevel_manufact = False @api.onchange('is_product_sublevel_manufact') def _onchange_is_product_sublevel_manufact(self): if self.is_product_sublevel_manufact: self.is_procur_level_manufact = True @api.onchange('is_procur_level_purchase') def _onchange_is_procur_level_purchase(self): if not self.is_procur_level_purchase: self.is_procur_sublevel_purchase = False @api.onchange('is_procur_sublevel_purchase') def _onchange_is_procur_sublevel_purchase(self): if self.is_procur_sublevel_purchase: self.is_procur_level_purchase = True
class plan_mejoramientos_wizard_reporte_plan(models.TransientModel): _name = 'plan_mejoramiento.wizard.reporte_plan' # ------------------- # Fields # ------------------- archivo = fields.Binary('Archivo',readonly=True,filters="xls") nombre_archivo = fields.Char('Nombre del Archivo', size=255) tipo = fields.Selection( TIPO_PLAN, string='Tipo', required=True, track_visibility='onchange', help='''Topo''', ) plan_id = fields.Many2one( string='Plan de Mejoramiento', required=True, track_visibility='onchange', comodel_name='plan_mejoramiento.plan', ondelete='restrict', help='''Plan de Mejoramiento''', domain="[('tipo','=',tipo)]", ) # ------------------- # methods # ------------------- def definir_plan(self, dic_plan, obj_plan={}): if obj_plan: dic_plan['plan_id'] = obj_plan.id or '' dic_plan['plan_nombre'] = obj_plan.name or '' dic_plan['plan_fecha'] = obj_plan.fecha or '' dic_plan['plan_origen'] = obj_plan.origen_id.name or '' dic_plan['plan_sub_origen'] = obj_plan.sub_origen_id.name or '' dic_plan['plan_unidad'] = obj_plan.dependencia_id.name or '' dic_plan['plan_usuario'] = obj_plan.user_id.name or '' dic_plan['plan_radicado'] = obj_plan.radicado or '' else: dic_plan['plan_id'] = '' dic_plan['plan_nombre'] = '' dic_plan['plan_fecha'] = '' dic_plan['plan_origen'] = '' dic_plan['plan_sub_origen'] = '' dic_plan['plan_unidad'] = '' dic_plan['plan_usuario'] = '' dic_plan['plan_radicado'] = '' def definir_hallazgo(self, dic_hallazgo, obj_hallazgo={}): if obj_hallazgo: dic_hallazgo['hallazgo_nombre'] = obj_hallazgo.name or '' dic_hallazgo['hallazgo_descripcion'] = obj_hallazgo.descripcion or '' dic_hallazgo['hallazgo_unidad'] = obj_hallazgo.dependencia_id.name or '' dic_hallazgo['hallazgo_causa'] = self.consolidar_causa (obj_hallazgo.causa_ids) or '' else: dic_hallazgo['hallazgo_nombre'] = '' dic_hallazgo['hallazgo_descripcion'] = '' dic_hallazgo['hallazgo_unidad'] = '' dic_hallazgo['hallazgo_causa'] = '' def definir_accion(self, dic_accion, obj_accion={}): if obj_accion: dic_accion['accion_nombre'] = obj_accion.name or '' dic_accion['accion_descripcion'] = obj_accion.descripcion or '' dic_accion['accion_tipo'] = obj_accion.tipo or '' dic_accion['accion_objetivo'] = obj_accion.objetivo or '' dic_accion['accion_indicador'] = obj_accion.indicador or '' dic_accion['accion_meta'] = obj_accion.meta or '' dic_accion['accion_unidad_medida'] = obj_accion.unidad_medida or '' dic_accion['accion_unidad'] = obj_accion.dependencia_id.name or '' dic_accion['accion_recursos'] = self.consolidar_recurso(obj_accion.recurso_ids) or '' dic_accion['accion_fecha_inicio'] = obj_accion.fecha_inicio or '' dic_accion['accion_fecha_fin'] = obj_accion.fecha_inicio or '' dic_accion['accion_estado'] = obj_accion.state or '' dic_accion['accion_ejecutor'] = obj_accion.ejecutor_id.name or '' else: dic_accion['accion_nombre'] = '' dic_accion['accion_descripcion'] = '' dic_accion['accion_tipo'] = '' dic_accion['accion_objetivo'] = '' dic_accion['accion_indicador'] = '' dic_accion['accion_meta'] = '' dic_accion['accion_unidad_medida'] = '' dic_accion['accion_unidad'] = '' dic_accion['accion_recursos'] = '' dic_accion['accion_fecha_inicio'] = '' dic_accion['accion_fecha_fin'] = '' dic_accion['accion_estado'] = '' dic_accion['accion_ejecutor'] = '' def definir_avance(self, dic_avance, obj_avance={}): if obj_avance: dic_avance['avance_descripcion'] = obj_avance.descripcion or '' dic_avance['avance_state'] = obj_avance.state or '' dic_avance['avance_calificacion'] = obj_avance.tipo_calificacion_id.name or '' dic_avance['avance_porcentaje_avance'] = obj_avance.porcentaje_avance or '' dic_avance['avance_observacion'] = obj_avance.observacion or '' dic_avance['avance_fecha_creacion'] = obj_avance.fecha_creacion or '' else: dic_avance['avance_descripcion'] = '' dic_avance['avance_state'] = '' dic_avance['avance_calificacion'] = '' dic_avance['avance_porcentaje_avance'] = '' dic_avance['avance_observacion'] = '' dic_avance['avance_fecha_creacion'] = '' def avance_actual(self, plan_id, plan_tipo, accion_id): # visitas = self.env['urbanizadores.proyecto.visita'].search([('proyecto_id', '=', proyecto.id)]) avance_max = self.env['plan_mejoramiento.avance'].search( [ ('plan_id', '=', plan_id), ('plan_tipo', '=', plan_tipo), ('accion_id', '=', accion_id), ], order='fecha_creacion DESC', limit=1, ) return avance_max def consolidar_causa(self, causa_ids): all_causa = '' for causa in causa_ids: all_causa = all_causa + causa.name + ', ' return all_causa def consolidar_recurso(self, recurso_ids): all_recurso = '' for recurso in recurso_ids: all_recurso = all_recurso + recurso.name + ', ' return all_recurso @api.multi def crear_reporte_plan(self): all_data = [] # construir diccionario if (self.plan_id.hallazgo_ids): for hallazgo in self.plan_id.hallazgo_ids: plan = {} if (hallazgo.accion_ids): for accion in hallazgo.accion_ids: if(accion.avance_ids): if (len(accion.avance_ids) >= 2): avance_max = self.avance_actual(self.plan_id.id, self.plan_id.tipo, accion.id) else: avance_max = accion.avance_ids self.definir_plan(plan, self.plan_id) self.definir_hallazgo(plan, hallazgo) self.definir_accion(plan, accion) self.definir_avance(plan, avance_max) all_data.append(plan) plan = {} else: self.definir_plan(plan, self.plan_id) self.definir_hallazgo(plan, hallazgo) self.definir_accion(plan, accion) self.definir_avance(plan) all_data.append(plan) plan = {} else: self.definir_plan(plan, self.plan_id) self.definir_hallazgo(plan, hallazgo) self.definir_accion(plan) self.definir_avance(plan) all_data.append(plan) plan = {} else: plan = {} self.definir_plan(plan, self.plan_id) self.definir_hallazgo(plan) self.definir_accion(plan) self.definir_avance(plan) all_data.append(plan) if (self.tipo == 'interno'): # crear reporte documento = reportes.crear_reporte( self, all_data, 'PLAN_INTERNO', 'xls', 'plan_interno.ods', 'plan_mejoramiento_ruta_plantilla_reportes' ) elif (self.tipo == 'contraloria_bog'): documento = reportes.crear_reporte( self, all_data, 'PLAN_BOGOTA', 'xls', 'plan_bogota.ods', 'plan_mejoramiento_ruta_plantilla_reportes' ) elif (self.tipo == 'contraloria_gral'): documento = reportes.crear_reporte( self, all_data, 'PLAN_GENERAL', 'xls', 'plan_general.ods', 'plan_mejoramiento_ruta_plantilla_reportes' ) # eliminar imagenes reportes.limpiar_carpeta('/tmp/img_reporte') # nombre del reporte para campos de odoo self.archivo = documento[0] self.nombre_archivo = documento[1] # buscamos el wizar de descarga view_ids = self.env['ir.ui.view'].search([('model','=','plan_mejoramiento.wizard.reporte_plan'), ('name','=','plan_mejoramiento.wizard.reporte_plan_download')]) ids = self.id return { 'view_type':'form', 'view_mode':'form', 'res_model':'plan_mejoramiento.wizard.reporte_plan', 'target':'new', 'type':'ir.actions.act_window', 'view_id':view_ids.id, 'res_id': ids }
class OperationDefinition(models.Model): _name = "hc.res.operation.definition" _description = "Operation Definition" url = fields.Char( string="URI", help="Logical URI to reference this operation definition.") version = fields.Char( string="Version", help="Logical id for this version of the operation definition.") name = fields.Char(string="Name", required="True", help="Informal name for this profile.") status = fields.Selection( string="Status", required="True", selection=[("draft", "Draft"), ("active", "Active"), ("retired", "Retired")], help= "The status of this operation definition. Enables tracking the life-cycle of the content." ) kind = fields.Selection( string="Kind", required="True", selection=[("operation", "Operation"), ("query", "Query")], help="Whether this is an operation or a named query.") is_experimental = fields.Boolean( string="Experimental", help="If for testing purposes, not real usage.") date = fields.Datetime( string="Date", help="Date for this version of the operation definition.") publisher = fields.Char( string="Publisher", help="Name of the publisher (Organization or individual).") contact_ids = fields.One2many( comodel_name="hc.operation.definition.contact", inverse_name="operation_definition_id", string="Contacts", help="Contact details for the publisher.") description = fields.Text( string="Description", help="Natural language description of the operation.") use_context_ids = fields.One2many( comodel_name="hc.operation.definition.use.context", inverse_name="operation_definition_id", string="Use Contexts", help="Content intends to support these contexts.") jurisdiction_ids = fields.Many2many( comodel_name="hc.vs.jurisdiction", relation="operation_definition_jurisdiction_rel", string="Jurisdictions", help="Intended jurisdiction for operation definition (if applicable).") purpose = fields.Text(string="Purpose", help="Why this operation definition is defined.") is_idempotent = fields.Boolean( string="Idempotent", help="Whether operation causes changes to content.") code_id = fields.Many2one(comodel_name="hc.vs.operation.definition.code", string="Code", required="True", help="Name used to invoke the operation.") comment = fields.Text(string="Comment", help="Additional information about use.") base_id = fields.Many2one(comodel_name="hc.res.operation.definition", string="Base", help="Marks this as a profile of the base.") resource_ids = fields.Many2many( comodel_name="hc.vs.resource.type", relation="operation_definition_resource_rel", string="Resources", help="Types this operation applies to.") is_system = fields.Boolean(string="System", required="True", help="Invoke at the system level?") is_type = fields.Boolean(string="Type", required="True", help="Invoke at the type level?") is_instance = fields.Boolean(string="Instance", required="True", help="Invoke on an instance?") parameter_ids = fields.One2many( comodel_name="hc.operation.definition.parameter", inverse_name="operation_definition_id", string="Parameters", help="Parameters for the operation/query.") overload_ids = fields.One2many( comodel_name="hc.operation.definition.overload", inverse_name="operation_definition_id", string="Overloads", help="For generating overloaded methods in code.")
class AccountCheckDeposit(models.Model): _name = "account.check.deposit" _description = "Account Check Deposit" _order = 'deposit_date desc' @api.multi @api.depends('company_id', 'currency_id', 'check_payment_ids.debit', 'check_payment_ids.amount_currency', 'move_id.line_id.reconcile_id') def _compute_check_deposit(self): for deposit in self: total = 0.0 count = 0 reconcile = False currency_none_same_company_id = False if deposit.company_id.currency_id != deposit.currency_id: currency_none_same_company_id = deposit.currency_id.id for line in deposit.check_payment_ids: count += 1 if currency_none_same_company_id: total += line.amount_currency else: total += line.debit if deposit.move_id: for line in deposit.move_id.line_id: if line.debit > 0 and line.reconcile_id: reconcile = True deposit.total_amount = total deposit.is_reconcile = reconcile deposit.currency_none_same_company_id =\ currency_none_same_company_id deposit.check_count = count name = fields.Char(string='Name', size=64, readonly=True, default='/') check_payment_ids = fields.One2many( 'account.move.line', 'check_deposit_id', string='Check Payments', states={'done': [('readonly', '=', True)]}) deposit_date = fields.Date(string='Deposit Date', required=True, states={'done': [('readonly', '=', True)]}, default=fields.Date.context_today) journal_id = fields.Many2one('account.journal', string='Journal', domain=[('type', '=', 'bank')], required=True, states={'done': [('readonly', '=', True)]}) journal_default_account_id = fields.Many2one( 'account.account', related='journal_id.default_debit_account_id', string='Default Debit Account of the Journal', readonly=True) currency_id = fields.Many2one('res.currency', string='Currency', required=True, states={'done': [('readonly', '=', True)]}) currency_none_same_company_id = fields.Many2one( 'res.currency', compute='_compute_check_deposit', string='Currency (False if same as company)') state = fields.Selection([ ('draft', 'Draft'), ('done', 'Done'), ], string='Status', default='draft', readonly=True) move_id = fields.Many2one('account.move', string='Journal Entry', readonly=True) partner_bank_id = fields.Many2one( 'res.partner.bank', string='Bank Account', required=True, domain="[('company_id', '=', company_id)]", states={'done': [('readonly', '=', True)]}) line_ids = fields.One2many('account.move.line', related='move_id.line_id', string='Lines', readonly=True) company_id = fields.Many2one('res.company', string='Company', required=True, states={'done': [('readonly', '=', True)]}, default=lambda self: self.env['res.company']. _company_default_get('account.check.deposit')) total_amount = fields.Float(compute='_compute_check_deposit', string="Total Amount", readonly=True, digits=dp.get_precision('Account')) check_count = fields.Integer(compute='_compute_check_deposit', readonly=True, string="Number of Checks") is_reconcile = fields.Boolean(compute='_compute_check_deposit', readonly=True, string="Reconcile") @api.multi @api.constrains('currency_id', 'check_payment_ids', 'company_id') def _check_deposit(self): for deposit in self: deposit_currency = deposit.currency_id if deposit_currency == deposit.company_id.currency_id: for line in deposit.check_payment_ids: if line.currency_id: raise ValidationError( _("The check with amount %s and reference '%s' " "is in currency %s but the deposit is in " "currency %s.") % (line.debit, line.ref or '', line.currency_id.name, deposit_currency.name)) else: for line in deposit.check_payment_ids: if line.currency_id != deposit_currency: raise ValidationError( _("The check with amount %s and reference '%s' " "is in currency %s but the deposit is in " "currency %s.") % (line.debit, line.ref or '', line.currency_id.name, deposit_currency.name)) @api.multi def unlink(self): for deposit in self: if deposit.state == 'done': raise UserError( _("The deposit '%s' is in valid state, so you must " "cancel it before deleting it.") % deposit.name) return super(AccountCheckDeposit, self).unlink() @api.multi def backtodraft(self): for deposit in self: if deposit.move_id: # It will raise here if journal_id.update_posted = False deposit.move_id.button_cancel() for line in deposit.check_payment_ids: if line.reconcile_id: line.reconcile_id.unlink() deposit.move_id.unlink() deposit.write({'state': 'draft'}) return True @api.model def create(self, vals): if vals.get('name', '/') == '/': vals['name'] = self.env['ir.sequence'].\ next_by_code('account.check.deposit') return super(AccountCheckDeposit, self).create(vals) @api.model def _prepare_account_move_vals(self, deposit): date = deposit.deposit_date period_obj = self.env['account.period'] period_ids = period_obj.find(dt=date) # period_ids will always have a value, cf the code of find() move_vals = { 'journal_id': deposit.journal_id.id, 'date': date, 'period_id': period_ids[0].id, 'name': _('Check Deposit %s') % deposit.name, 'ref': deposit.name, } return move_vals @api.model def _prepare_move_line_vals(self, line): assert (line.debit > 0), 'Debit must have a value' return { 'name': _('Check Deposit - Ref. Check %s') % line.ref, 'credit': line.debit, 'debit': 0.0, 'account_id': line.account_id.id, 'partner_id': line.partner_id.id, 'currency_id': line.currency_id.id or False, 'amount_currency': line.amount_currency * -1, } @api.model def _prepare_counterpart_move_lines_vals(self, deposit, total_debit, total_amount_currency): return { 'name': _('Check Deposit %s') % deposit.name, 'debit': total_debit, 'credit': 0.0, 'account_id': deposit.company_id.check_deposit_account_id.id, 'partner_id': False, 'currency_id': deposit.currency_none_same_company_id.id or False, 'amount_currency': total_amount_currency, } @api.multi def validate_deposit(self): am_obj = self.env['account.move'] aml_obj = self.env['account.move.line'] for deposit in self: move_vals = self._prepare_account_move_vals(deposit) move = am_obj.create(move_vals) total_debit = 0.0 total_amount_currency = 0.0 to_reconcile_lines = [] for line in deposit.check_payment_ids: total_debit += line.debit total_amount_currency += line.amount_currency line_vals = self._prepare_move_line_vals(line) line_vals['move_id'] = move.id move_line = aml_obj.create(line_vals) to_reconcile_lines.append(line + move_line) # Create counter-part if not deposit.company_id.check_deposit_account_id: raise UserError( _("Missing Account for Check Deposits on the " "company '%s'.") % deposit.company_id.name) counter_vals = self._prepare_counterpart_move_lines_vals( deposit, total_debit, total_amount_currency) counter_vals['move_id'] = move.id aml_obj.create(counter_vals) move.post() deposit.write({'state': 'done', 'move_id': move.id}) # We have to reconcile after post() for reconcile_lines in to_reconcile_lines: reconcile_lines.reconcile() return True @api.onchange('company_id') def onchange_company_id(self): if self.company_id: partner_banks = self.env['res.partner.bank'].search([ ('company_id', '=', self.company_id.id) ]) if len(partner_banks) == 1: self.partner_bank_id = partner_banks[0] else: self.partner_bank_id = False @api.onchange('journal_id') def onchange_journal_id(self): if self.journal_id: if self.journal_id.currency: self.currency_id = self.journal_id.currency else: self.currency_id = self.journal_id.company_id.currency_id
class sbg_subscriptions(models.Model): _name = 'sbg.subscriptions' _description = 'Subscriptions' partner_id = fields.Many2one('res.partner', 'Partner', ondelete='set null', select=True) subscription_service_id = fields.Many2one('sbg.subscription.services', 'Service', ondelete='set null', select=True) name = fields.Char(string="Name", related='subscription_service_id.name') fee = fields.Float(string="Fee", related='subscription_service_id.fee') start_date = fields.Date(string="Start date") statement_ids = fields.One2many('sbg.subscription.statement', 'subscription_id', string='Statement') active = fields.Boolean(string="Active", default=True) @api.model def create(self, values): record = super(sbg_subscriptions, self).create(values) service_rec = self.env['sbg.subscription.services'].search([ ('id', '=', values['subscription_service_id']) ]) start_date = datetime.strptime(record['start_date'], '%Y-%m-%d') if service_rec['start_date'] > record['start_date']: start_date = datetime.strptime(service_rec['start_date'], '%Y-%m-%d') start_date = datetime(start_date.year, start_date.month, 1) months = 1 if service_rec['periodicity'] == 'b': months = 2 elif service_rec['periodicity'] == 'q': months = 3 elif service_rec['periodicity'] == 's': months = 6 elif service_rec['periodicity'] == 'a': months = 12 start_month = start_date.month remainder = start_month % months if remainder > 0: start_month = start_month + (months - start_month % months) date = datetime(start_date.year, start_month, 1) end_date = datetime(start_date.year, 12, 31) if service_rec['duration_type'] == 'fees_quantity': end_date = date for i in range(1, service_rec['fees_quantity'] + 1): end_date += relativedelta(months=months) if end_date < datetime.strptime(service_rec['end_date'], '%Y-%m-%d'): end_date = datetime.strptime(service_rec['end_date'], '%Y-%m-%d') while date < end_date: data = { 'subscription_id': record['id'], 'date': date, 'value': service_rec['fee'], 'active': True } self.env['sbg.subscription.statement'].create(data) date += relativedelta(months=months) return record
class contract_group(models.Model): _name = 'recurring.contract.group' _description = 'A group of contracts' _inherit = 'mail.thread' _rec_name = 'ref' ########################################################################## # FIELDS # ########################################################################## # TODO Add unit for advance_billing advance_billing_months = fields.Integer( 'Advance billing months', help=_( 'Advance billing allows you to generate invoices in ' 'advance. For example, you can generate the invoices ' 'for each month of the year and send them to the ' 'customer in january.' ), default=1, ondelete='no action') payment_term_id = fields.Many2one('account.payment.term', 'Payment Term', track_visibility="onchange") next_invoice_date = fields.Date( compute='_set_next_invoice_date', string='Next invoice date', store=True) last_paid_invoice_date = fields.Date( compute='_set_last_paid_invoice', string='Last paid invoice date') change_method = fields.Selection( '_get_change_methods', default='do_nothing') partner_id = fields.Many2one( 'res.partner', 'Partner', required=True, ondelete='cascade', track_visibility="onchange") ref = fields.Char('Reference', default="/") recurring_unit = fields.Selection([ ('day', _('Day(s)')), ('week', _('Week(s)')), ('month', _('Month(s)')), ('year', _('Year(s)'))], 'Reccurency', default='month', required=True) recurring_value = fields.Integer( 'Generate every', default=1, required=True) contract_ids = fields.One2many( 'recurring.contract', 'group_id', 'Contracts', readonly=True) ########################################################################## # FIELDS METHODS # ########################################################################## @api.depends('contract_ids.next_invoice_date', 'contract_ids.state') @api.one def _set_next_invoice_date(self): next_inv_date = min( [c.next_invoice_date for c in self.contract_ids if c.state in self._get_gen_states()] or [False]) self.next_invoice_date = next_inv_date @api.multi def _set_last_paid_invoice(self): for group in self: group.last_paid_invoice_date = max( [c.last_paid_invoice_date for c in group.contract_ids] or [False]) ########################################################################## # ORM METHODS # ########################################################################## @api.multi def write(self, vals): """ Perform various check at contract modifications - Advance billing increased or decrease - Recurring value or unit changes - Another change method was selected """ res = True for group in self: # Check if group has an next_invoice_date if not group.next_invoice_date or 'next_invoice_date' in vals: res = super(contract_group, group).write(vals) and res continue # Get the method to apply changes change_method = vals.get('change_method', group.change_method) change_method = getattr(group, change_method) res = super(contract_group, group).write(vals) & res change_method() return res ########################################################################## # PUBLIC METHODS # ########################################################################## @api.multi def button_generate_invoices(self): invoicer = self.generate_invoices() self.validate_invoices(invoicer) return invoicer @api.model def validate_invoices(self, invoicer): # Check if there is invoice waiting for validation if invoicer.invoice_ids: invoicer.validate_invoices() @api.multi def clean_invoices(self): """ By default, launch asynchronous job to perform the task. Context value async_mode set to False can force to perform the task immediately. """ if self.env.context.get('async_mode', True): session = ConnectorSession.from_env(self.env) clean_generate_job.delay(session, self._name, self.ids) else: self._clean_generate_invoices() return True def do_nothing(self): """ No changes before generation """ pass def generate_invoices(self, invoicer=None): """ By default, launch asynchronous job to perform the task. Context value async_mode set to False can force to perform the task immediately. """ if invoicer is None: invoicer = self.env['recurring.invoicer'].create( {'source': self._name}) if self.env.context.get('async_mode', True): session = ConnectorSession.from_env(self.env) generate_invoices_job.delay( session, self._name, self.ids, invoicer.id) else: # Prevent two generations at the same time jobs = self.env['queue.job'].search([ ('channel', '=', 'root.recurring_invoicer'), ('state', '=', 'started')]) if jobs: raise exceptions.Warning( _("Generation already running"), _("A generation has already started in background. " "Please wait for it to finish.")) self._generate_invoices(invoicer) return invoicer ########################################################################## # PRIVATE METHODS # ########################################################################## def _generate_invoices(self, invoicer=None): """ Checks all contracts and generate invoices if needed. Create an invoice per contract group per date. """ logger.info("Invoice generation started.") if invoicer is None: invoicer = self.env['recurring.invoicer'].create( {'source': self._name}) inv_obj = self.env['account.invoice'] journal_obj = self.env['account.journal'] gen_states = self._get_gen_states() journal_ids = journal_obj.search( [('type', '=', 'sale'), ('company_id', '=', 1 or False)], limit=1) nb_groups = len(self) count = 1 for contract_group in self: logger.info("Generating invoices for group {0}/{1}".format( count, nb_groups)) month_delta = contract_group.advance_billing_months or 1 limit_date = datetime.today() + relativedelta(months=+month_delta) while True: # Emulate a do-while loop # contract_group update 'cause next_inv_date has been modified group_inv_date = contract_group.next_invoice_date contracts = self.env['recurring.contract'] if group_inv_date and datetime.strptime(group_inv_date, DF) <= limit_date: contracts = contract_group.contract_ids.filtered( lambda c: c.next_invoice_date <= group_inv_date and (not c.end_date or c.end_date > c.next_invoice_date) and c.state in gen_states) if not contracts: break inv_data = contract_group._setup_inv_data(journal_ids, invoicer) invoice = inv_obj.create(inv_data) for contract in contracts: contract_group._generate_invoice_lines(contract, invoice) if invoice.invoice_line: invoice.button_compute() else: invoice.unlink() # After a contract_group is done, we commit all writes in order to # avoid doing it again in case of an error or a timeout self.env.cr.commit() count += 1 logger.info("Invoice generation successfully finished.") return invoicer @api.multi def _clean_generate_invoices(self): """ Change method which cancels generated invoices and rewinds the next_invoice_date of contracts, so that new invoices can be generated taking into consideration the modifications of the contract group. """ res = self.env['account.invoice'] for group in self: since_date = datetime.today() if group.last_paid_invoice_date: last_paid_invoice_date = datetime.strptime( group.last_paid_invoice_date, DF) since_date = max(since_date, last_paid_invoice_date) res += group.contract_ids._clean_invoices( since_date=since_date.strftime(DF)) group.contract_ids.rewind_next_invoice_date() # Generate again invoices invoicer = self._generate_invoices() self.validate_invoices(invoicer) return res @api.multi def _get_change_methods(self): """ Method for applying changes """ return [ ('do_nothing', 'Nothing'), ('clean_invoices', 'Clean invoices') ] def _get_gen_states(self): return ['active'] def _setup_inv_data(self, journal_ids, invoicer): """ Setup a dict with data passed to invoice.create. If any custom data is wanted in invoice from contract group, just inherit this method. """ partner = self.partner_id inv_data = { 'account_id': partner.property_account_receivable.id, 'type': 'out_invoice', 'partner_id': partner.id, 'journal_id': len(journal_ids) and journal_ids[0].id or False, 'currency_id': partner.property_product_pricelist.currency_id.id or False, 'date_invoice': self.next_invoice_date, 'recurring_invoicer_id': invoicer.id, 'payment_term': self.payment_term_id and self.payment_term_id.id or False, } return inv_data @api.multi def _setup_inv_line_data(self, contract_line, invoice): """ Setup a dict with data passed to invoice_line.create. If any custom data is wanted in invoice line from contract, just inherit this method. """ product = contract_line.product_id account = product.property_account_income inv_line_data = { 'name': product.name, 'price_unit': contract_line.amount or 0.0, 'quantity': contract_line.quantity, 'uos_id': False, 'product_id': product.id or False, 'invoice_id': invoice.id, 'contract_id': contract_line.contract_id.id, } if account: inv_line_data['account_id'] = account.id return inv_line_data @api.model def _generate_invoice_lines(self, contract, invoice): inv_line_obj = self.env['account.invoice.line'] for contract_line in contract.contract_line_ids: inv_line_data = self._setup_inv_line_data(contract_line, invoice) if inv_line_data: inv_line_obj.create(inv_line_data) if not self.env.context.get('no_next_date_update'): contract.update_next_invoice_date()
class WaveReportWizard(models.TransientModel): _name = 'wave.report.wizard' wave_id = fields.Many2one( 'stock.picking.wave', 'Picking Wave', ) file = fields.Binary( 'Production', attachment=True, readonly=True, ) filename = fields.Char(string="Production filename", ) # Header include_partner = fields.Boolean( 'Include partner', default=True, ) include_warehouse = fields.Boolean( 'Include warehouse', default=False, ) @api.multi def get_production_report(self): productions = self.wave_id.procurement_production_ids routes = productions.mapped('routing_id') pickings = self.wave_id.picking_ids wb = openpyxl.Workbook() ws = wb.active ws.title = u'ORDENES DE PRODUCCIÓN' for route in routes: ws.append([route.name]) if self.include_partner: partner_header = ['', ''] for picking in pickings: partner_header.append(picking.partner_id.name) ws.append(partner_header) if self.include_warehouse: warehouse_header = ['', ''] for picking in pickings: warehouse_header.append( picking.location_dest_id.location_id.name) ws.append(warehouse_header) header = [ _('PRODUCT'), _('TOTAL'), ] for picking in pickings: header.append(picking.name) ws.append(header) prod_obj = productions.filtered(lambda p: p.routing_id == route) for p in prod_obj: production_list = [ p.product_id.name, ] total = 0 picking_list = [] for sp in pickings: move = sp.move_lines_related.filtered( lambda x: x.product_id == p.product_id) m = sum(move.mapped('product_uom_qty')) picking_list.append(m or 0) total += m production_list.append(total) production_list += picking_list ws.append(production_list) # Genera un espacio vacío entre rutas. ws.append([ '', ]) output = StringIO() wb.save(output) xlsx_data = output.getvalue() self.write({ 'filename': 'produccion.xlsx', 'file': base64.encodestring(xlsx_data) }) return { 'type': 'ir.actions.act_window', 'res_model': 'wave.report.wizard', 'view_type': 'form', 'view_mode': 'form', 'res_id': self.id, 'target': 'new', 'context': self._context, }
class ExtendsResCompany(models.Model): _name = 'res.company' _inherit = 'res.company' findo_configuracion_id = fields.Many2one('financiera.findo.configuracion', 'Configuracion Findo')
class is_action(models.Model): _name = "is.action" _description = "Actions" _order='date_creation desc, name' @api.depends('ordinateur_id','utilisateur_id') def _compute(self): for obj in self: if obj.utilisateur_id.service_id.id: obj.service_id=obj.utilisateur_id.service_id.id if obj.utilisateur_id.site_id.id: obj.site_id=obj.utilisateur_id.site_id.id else: if obj.ordinateur_id.site_id.id: obj.site_id=obj.ordinateur_id.site_id.id action_globale_id = fields.Many2one('is.action.globale', 'Action globale') name = fields.Char('Action', required=True) ordinateur_id = fields.Many2one('is.ordinateur', 'Ordinateur') utilisateur_id = fields.Many2one('is.utilisateur', 'Utilisateur') site_id = fields.Many2one('is.site' , 'Site' , compute='_compute', readonly=True, store=True) service_id = fields.Many2one('is.service', 'Service', compute='_compute', readonly=True, store=True) mail = fields.Char('Mail', related='utilisateur_id.mail', readonly=True) date_creation = fields.Date('Date création', required=True) date_prevue = fields.Date('Date prévue' , required=True) tps_prevu = fields.Float("Temps prévu (H)") date_realisee = fields.Date('Date réalisée') tps_passe = fields.Float("Temps passé (H)") commentaire = fields.Text('Commentaire') _defaults = { 'date_creation': lambda *a: _date_creation(), } @api.multi def solder_action_action(self): for obj in self: if obj.action_globale_id.date_realisee: if obj.date_realisee==False: obj.date_realisee=obj.action_globale_id.date_realisee @api.multi def actualiser_service_action(self): for obj in self: if obj.service_id.id==False: if obj.utilisateur_id.id!=False: service_id=obj.utilisateur_id.service_id.id else: service_id=obj.ordinateur_id.service_id.id if service_id: obj.service_id=service_id @api.multi def acceder_action(self): for obj in self: return { 'name': u'Action '+obj.name or '', 'view_mode': 'form,tree', 'view_type': 'form', 'res_model': 'is.action', 'res_id': obj.id, 'type': 'ir.actions.act_window', } @api.model def create(self, vals): obj = super(is_action, self).create(vals) obj.action_globale_id._compute_avancement() return obj @api.multi def write(self, vals): res=super(is_action, self).write(vals) for obj in self: if obj.action_globale_id: obj.action_globale_id._compute_avancement() return res @api.multi def ordinateur_id_on_change(self,ordinateur_id,utilisateur_id): res={} if ordinateur_id: res['value']={} ordinateur = self.env['is.ordinateur'].browse(ordinateur_id) utilisateur_id=ordinateur.utilisateur_id.id if utilisateur_id: res['value']['utilisateur_id']=utilisateur_id return res @api.multi def utilisateur_id_on_change(self,ordinateur_id,utilisateur_id): res={} if utilisateur_id and ordinateur_id==False: res['value']={} ordinateurs = self.env['is.ordinateur'].search([('utilisateur_id','=',utilisateur_id)]) for ordinateur in ordinateurs: res['value']['ordinateur_id']=ordinateur.id return res
class OpStudent(models.Model): _inherit = 'op.student' category = fields.Many2one('op.category', 'Category') religion = fields.Many2one('op.religion', 'Religion') pan_card = fields.Char('PAN Card', size=16)
class TmsTravel(models.Model): _name = 'tms.travel' _inherit = ['mail.thread', 'ir.needaction_mixin'] _description = 'Travel' _order = "date desc" waybill_ids = fields.Many2many('tms.waybill', string='Waybills') driver_factor_ids = fields.One2many('tms.factor', 'travel_id', string='Travel Driver Payment Factors', domain=[('category', '=', 'driver')]) name = fields.Char('Travel Number') state = fields.Selection([('draft', 'Pending'), ('progress', 'In Progress'), ('done', 'Done'), ('cancel', 'Cancelled'), ('closed', 'Closed')], 'State', readonly=True, default='draft') route_id = fields.Many2one('tms.route', 'Route', required=True, states={ 'cancel': [('readonly', True)], 'closed': [('readonly', True)] }) travel_duration = fields.Float(compute='_compute_travel_duration', string='Duration Sched', help='Travel Scheduled duration in hours') travel_duration_real = fields.Float( compute='_compute_travel_duration_real', string='Duration Real', help="Travel Real duration in hours") distance_route = fields.Float(related="route_id.distance", string='Route Distance (mi./km)') fuel_efficiency_expected = fields.Float( string='Fuel Efficiency Expected', compute="_compute_fuel_efficiency_expected") kit_id = fields.Many2one('tms.unit.kit', 'Kit') unit_id = fields.Many2one('fleet.vehicle', 'Unit', required=True) trailer1_id = fields.Many2one('fleet.vehicle', 'Trailer1') dolly_id = fields.Many2one('fleet.vehicle', 'Dolly', domain=[('fleet_type', '=', 'dolly')]) trailer2_id = fields.Many2one('fleet.vehicle', 'Trailer2', domain=[('fleet_type', '=', 'trailer')]) employee_id = fields.Many2one('hr.employee', 'Driver', required=True, domain=[('driver', '=', True)]) date = fields.Datetime('Date registered', required=True, default=(fields.Datetime.now)) date_start = fields.Datetime('Start Sched', default=(fields.Datetime.now)) date_end = fields.Datetime('End Sched', store=True, compute='_compute_date_end') date_start_real = fields.Datetime('Start Real') date_end_real = fields.Datetime('End Real') distance_driver = fields.Float('Distance traveled by driver (mi./km)', compute='_compute_distance_driver', store=True) distance_loaded = fields.Float('Distance Loaded (mi./km)') distance_empty = fields.Float('Distance Empty (mi./km)') odometer = fields.Float('Unit Odometer (mi./km)', readonly=True) fuel_efficiency_travel = fields.Float('Fuel Efficiency Travel') fuel_efficiency_extraction = fields.Float( compute='_compute_fuel_efficiency_extraction', string='Fuel Efficiency Extraction') departure_id = fields.Many2one('tms.place', related='route_id.departure_id', readonly=True) fuel_log_ids = fields.One2many('fleet.vehicle.log.fuel', 'travel_id', string='Fuel Vouchers') advance_ids = fields.One2many('tms.advance', 'travel_id', string='Advances') arrival_id = fields.Many2one('tms.place', related='route_id.arrival_id', readonly=True) notes = fields.Text('Description') user_id = fields.Many2one('res.users', 'Responsable', default=lambda self: self.env.user) expense_id = fields.Many2one('tms.expense', 'Expense Record', readonly=True) event_ids = fields.One2many('tms.event', 'travel_id', string='Events') is_available = fields.Boolean(compute='_compute_is_available', string='Travel available') operating_unit_id = fields.Many2one('operating.unit', 'Operating Unit') color = fields.Integer() framework = fields.Selection([('unit', 'Unit'), ('single', 'Single'), ('double', 'Double')], compute='_compute_framework') partner_ids = fields.Many2many('res.partner', string='Customer', compute='_compute_partner_ids') @api.depends('waybill_ids') def _compute_partner_ids(self): for rec in self: partner_ids = [] for waybill in rec.waybill_ids: partner_ids.append(waybill.partner_id.id) rec.partner_ids = partner_ids @api.depends('fuel_efficiency_expected', 'fuel_efficiency_travel') def _compute_fuel_efficiency_extraction(self): for rec in self: rec.fuel_efficiency_extraction = (rec.fuel_efficiency_expected - rec.fuel_efficiency_travel) @api.depends('date_start') def _compute_date_end(self): for rec in self: if rec.date_start: strp_date = datetime.strptime(rec.date_start, "%Y-%m-%d %H:%M:%S") rec.date_end = strp_date + timedelta( hours=rec.route_id.travel_time) @api.depends('date_start', 'date_end') def _compute_travel_duration(self): for rec in self: if rec.date_start and rec.date_end: start_date = datetime.strptime(rec.date_start, "%Y-%m-%d %H:%M:%S") end_date = datetime.strptime(rec.date_end, "%Y-%m-%d %H:%M:%S") difference = (end_date - start_date).total_seconds() / 60 / 60 rec.travel_duration = difference @api.depends('date_start_real', 'date_end_real') def _compute_travel_duration_real(self): for rec in self: if rec.date_start_real and rec.date_end_real: start_date = datetime.strptime(rec.date_start_real, "%Y-%m-%d %H:%M:%S") end_date = datetime.strptime(rec.date_end_real, "%Y-%m-%d %H:%M:%S") difference = (end_date - start_date).total_seconds() / 60 / 60 rec.travel_duration_real = difference @api.onchange('kit_id') def _onchange_kit(self): for rec in self: rec.unit_id = rec.kit_id.unit_id rec.trailer2_id = rec.kit_id.trailer2_id rec.trailer1_id = rec.kit_id.trailer1_id rec.dolly_id = rec.kit_id.dolly_id rec.employee_id = rec.kit_id.employee_id @api.onchange('route_id') def _onchange_route(self): self.driver_factor_ids = self.route_id.driver_factor_ids self.travel_duration = self.route_id.travel_time for rec in self: rec.driver_factor_ids = rec.route_id.driver_factor_ids rec.distance_route = rec.route_id.distance rec.distance_loaded = rec.route_id.distance_loaded rec.distance_empty = rec.route_id.distance_empty @api.depends('distance_empty', 'distance_loaded') def _compute_distance_driver(self): for rec in self: rec.distance_driver = rec.distance_empty + rec.distance_loaded @api.multi def action_draft(self): for rec in self: rec.state = "draft" @api.multi def action_progress(self): for rec in self: rec.validate_driver_license() rec.validate_vehicle_insurance() travels = rec.search([('state', '=', 'progress'), '|', ('employee_id', '=', rec.employee_id.id), ('unit_id', '=', rec.unit_id.id)]) if len(travels) >= 1: raise ValidationError( _('The unit or driver are already in use!')) rec.state = "progress" rec.date_start_real = fields.Datetime.now() rec.message_post('Travel Dispatched') @api.multi def action_done(self): for rec in self: odometer = self.env['fleet.vehicle.odometer'].create({ 'travel_id': rec.id, 'vehicle_id': rec.unit_id.id, 'last_odometer': rec.unit_id.odometer, 'distance': rec.distance_driver, 'current_odometer': rec.unit_id.odometer + rec.distance_driver, 'value': rec.unit_id.odometer + rec.distance_driver }) rec.state = "done" rec.odometer = odometer.current_odometer rec.date_end_real = fields.Datetime.now() rec.message_post('Travel Finished') @api.multi def action_cancel(self): for rec in self: advances = rec.advance_ids.search([('state', '!=', 'cancel'), ('travel_id', '=', rec.id)]) fuel_log = rec.fuel_log_ids.search([('state', '!=', 'cancel'), ('travel_id', '=', rec.id)]) if len(advances) >= 1 or len(fuel_log) >= 1: raise ValidationError( _('If you want to cancel this travel,' ' you must cancel the fuel logs or the advances ' 'attached to this travel')) rec.state = "cancel" rec.message_post('Travel Cancelled') @api.model def create(self, values): travel = super(TmsTravel, self).create(values) sequence = travel.operating_unit_id.travel_sequence_id travel.name = sequence.next_by_id() return travel @api.depends() def _compute_is_available(self): for rec in self: objects = ['tms.advance', 'fleet.vehicle.log.fuel', 'tms.waybill'] advances = len(rec.advance_ids) fuel_vehicle = len(rec.fuel_log_ids) count = 0 for model in objects: if model == 'tms.advance' or model == 'fleet.vehicle.log.fuel': object_ok = len(rec.env[model].search([ ('state', '=', 'confirmed'), ('travel_id', '=', rec.id) ])) if (model == 'tms.advance' and advances == object_ok or advances == 0): count += 1 elif (model == 'fleet.vehicle.log.fuel' and fuel_vehicle == object_ok or fuel_vehicle == 0): count += 1 if model == 'tms.waybill': object_ok = len(rec.env[model].search([ ('state', '=', 'confirmed'), ('travel_ids', 'in', rec.id) ])) if len(rec.waybill_ids) == object_ok: count += 1 if count == 3: rec.is_available = True @api.depends('route_id', 'framework') def _compute_fuel_efficiency_expected(self): for rec in self: res = self.env['tms.route.fuelefficiency'].search([ ('route_id', '=', rec.route_id.id), ('engine_id', '=', rec.unit_id.engine_id.id), ('type', '=', rec.framework) ]).performance rec.fuel_efficiency_expected = res @api.depends('trailer1_id', 'trailer2_id') def _compute_framework(self): for rec in self: if rec.trailer2_id: rec.framework = 'double' elif rec.trailer1_id: rec.framework = 'single' else: rec.framework = 'unit' @api.multi def validate_driver_license(self): val = self.env['ir.config_parameter'].get_param( 'driver_license_security_days') days = int(val) or 0 for rec in self: if rec.employee_id.days_to_expire <= days: raise ValidationError( _("You can not Dispatch this Travel because %s " "Driver's License Validity (%s) is expired or" " about to expire in next %s day(s)") % (rec.employee_id.name, rec.employee_id.license_expiration, val)) return True @api.multi def validate_vehicle_insurance(self): val = self.env['ir.config_parameter'].get_param( 'tms_vehicle_insurance_security_days') xdays = int(val) or 0 date = datetime.now() + timedelta(days=xdays) for rec in self: units = [ rec.unit_id, rec.trailer1_id, rec.dolly_id, rec.trailer2_id ] for unit in units: if (unit and unit.insurance_expiration and unit.insurance_expiration <= date.strftime('%Y-%m-%d')): raise ValidationError( _("You can not Dispatch this Travel because this Vehicle" "(%s) Insurance (%s) is expired or about to expire in " "next %s day(s)") % (rec.unit_id.name, rec.unit_id.insurance_expiration, val))
class WizardConsumeMaterial(models.TransientModel): _name = 'wizard.consume.material' @api.model def default_get(self, fields): res = super(WizardConsumeMaterial, self).default_get(fields) sale_order_consume_material_obj = self.env[ 'sale.order.consume.material'] active_id = self.env.context.get('active_id') or False sale_order_consume_material = sale_order_consume_material_obj.browse( active_id) res['consume_material_id'] = sale_order_consume_material.id res['product_id'] = sale_order_consume_material.product_id.id res['qty'] = sale_order_consume_material.quantity return res consume_material_id = fields.Many2one('sale.order.consume.material', 'Consume Material', readonly=True) product_id = fields.Many2one('product.product', 'Product', readonly=True) employee_id = fields.Many2one('hr.employee', 'Employee', required=True) qty = fields.Float('Claim Qty', required=True) @api.one def do_move_consume(self, cr, uid, ids, context=None): move_obj = self.env['stock.move'] uom_obj = self.env['product.uom'] production_obj = self.env['mrp.production'] move_ids = context['active_ids'] move = move_obj.browse(cr, uid, move_ids[0], context=context) production_id = move.raw_material_production_id.id production = production_obj.browse(cr, uid, production_id, context=context) precision = self.pool['decimal.precision'].precision_get( cr, uid, 'Product Unit of Measure') for data in self.browse(cr, uid, ids, context=context): qty = uom_obj._compute_qty(cr, uid, data['product_uom'].id, data.product_qty, data.product_id.uom_id.id) remaining_qty = move.product_qty - qty # check for product quantity is less than previously planned if float_compare(remaining_qty, 0, precision_digits=precision) >= 0: move_obj.action_consume( cr, uid, move_ids, qty, data.location_id.id, restrict_lot_id=data.restrict_lot_id.id, context=context) else: consumed_qty = min(move.product_qty, qty) new_moves = move_obj.action_consume( cr, uid, move_ids, consumed_qty, data.location_id.id, restrict_lot_id=data.restrict_lot_id.id, context=context) # consumed more in wizard than previously planned extra_more_qty = qty - consumed_qty # create new line for a remaining qty of the product extra_move_id = production_obj._make_consume_line_from_data( cr, uid, production, data.product_id, data.product_id.uom_id.id, extra_more_qty, context=context) move_obj.write(cr, uid, [extra_move_id], {'restrict_lot_id': data.restrict_lot_id.id}, context=context) move_obj.action_done(cr, uid, [extra_move_id], context=context) @api.one def process_consume_material(self): consume_material_id = self.consume_material_id consume_material_id.employee_id = self.employee_id.id consume_material_id.trans_consume_material() self.consume_material_id.sale_order_id.trans_merge_stock_move()
class AccountPaymentGroupInvoiceWizard(models.TransientModel): _name = "account.payment.group.invoice.wizard" @api.model def default_payment_group(self): return self.env['account.payment.group'].browse( self._context.get('active_id', False)) payment_group_id = fields.Many2one( 'account.payment.group', default=default_payment_group, ondelete='cascade', required=True, ) journal_id = fields.Many2one( 'account.journal', 'Journal', required=True, ondelete='cascade', ) date_invoice = fields.Date(string='Refund Date', default=fields.Date.context_today, required=True) currency_id = fields.Many2one( related='payment_group_id.currency_id', readonly=True, ) date = fields.Date(string='Accounting Date') product_id = fields.Many2one( 'product.product', required=True, domain=[('sale_ok', '=', True)], ) tax_ids = fields.Many2many( 'account.tax', string='Taxes', ) amount_untaxed = fields.Monetary( string='Untaxed Amount', required=True, compute='_compute_amount_untaxed', inverse='_inverse_amount_untaxed', ) # we make amount total the main one and the other computed because the # normal case of use would be to know the total amount and also this amount # is the suggested one on creating the wizard amount_total = fields.Monetary(string='Total Amount', required=True) description = fields.Char(string='Reason', ) company_id = fields.Many2one( related='payment_group_id.company_id', readonly=True, ) account_analytic_id = fields.Many2one( 'account.analytic.account', 'Analytic Account', ) @api.onchange('product_id') def change_product(self): self.ensure_one() if self.payment_group_id.partner_type == 'purchase': taxes = self.product_id.supplier_taxes_id else: taxes = self.product_id.taxes_id company = self.company_id or self.env.user.company_id taxes = taxes.filtered(lambda r: r.company_id == company) self.tax_ids = self.payment_group_id.partner_id.with_context( force_company=company.id).property_account_position_id.map_tax( taxes) @api.onchange('amount_untaxed', 'tax_ids') def _inverse_amount_untaxed(self): self.ensure_one() if self.tax_ids: taxes = self.tax_ids.compute_all( self.amount_untaxed, self.company_id.currency_id, 1.0, product=self.product_id, partner=self.payment_group_id.partner_id) self.amount_total = taxes['total_included'] else: self.amount_total = self.amount_untaxed @api.depends('tax_ids', 'amount_total') def _compute_amount_untaxed(self): """ For now we implement inverse only for percent taxes. We could extend to other by simulating tax.price_include = True, computing tax and then restoring tax.price_include = False. """ self.ensure_one() if any(x.amount_type != 'percent' for x in self.tax_ids): raise ValidationError( _('You can only set amount total if taxes are of type ' 'percentage')) tax_percent = sum( [x.amount for x in self.tax_ids if not x.price_include]) total_percent = (1 + tax_percent / 100) or 1.0 self.amount_untaxed = self.amount_total / total_percent @api.onchange('payment_group_id') def change_payment_group(self): journal_type = 'sale' type_tax_use = 'sale' if self.payment_group_id.partner_type == 'purchase': journal_type = 'purchase' type_tax_use = 'purchase' journal_domain = [ ('type', '=', journal_type), ('company_id', '=', self.payment_group_id.company_id.id), ] tax_domain = [('type_tax_use', '=', type_tax_use), ('company_id', '=', self.payment_group_id.company_id.id)] self.journal_id = self.env['account.journal'].search(journal_domain, limit=1) # usually debit/credit note will be for the payment difference self.amount_total = abs(self.payment_group_id.payment_difference) return { 'domain': { 'journal_id': journal_domain, 'tax_ids': tax_domain, } } @api.multi def get_invoice_vals(self): self.ensure_one() payment_group = self.payment_group_id if payment_group.partner_type == 'supplier': invoice_type = 'in_' else: invoice_type = 'out_' if self._context.get('refund'): invoice_type += 'refund' else: invoice_type += 'invoice' return { 'name': self.description, 'date': self.date, 'date_invoice': self.date_invoice, 'origin': _('Payment id %s') % payment_group.id, 'journal_id': self.journal_id.id, 'user_id': payment_group.partner_id.user_id.id, 'partner_id': payment_group.partner_id.id, 'type': invoice_type, # 'invoice_line_ids': [('invoice_type')], } @api.multi def confirm(self): self.ensure_one() invoice = self.env['account.invoice'].create(self.get_invoice_vals()) inv_line_vals = { 'product_id': self.product_id.id, 'price_unit': self.amount_untaxed, 'invoice_id': invoice.id, 'invoice_line_tax_ids': [(6, 0, self.tax_ids.ids)], } invoice_line = self.env['account.invoice.line'].new(inv_line_vals) invoice_line._onchange_product_id() # restore chosen taxes (changed by _onchange_product_id) invoice_line.invoice_line_tax_ids = self.tax_ids line_values = invoice_line._convert_to_write(invoice_line._cache) line_values['price_unit'] = self.amount_untaxed if self.account_analytic_id: line_values['account_analytic_id'] = self.account_analytic_id.id invoice.write({'invoice_line_ids': [(0, 0, line_values)]}) invoice.compute_taxes() invoice.signal_workflow('invoice_open') # TODO this FIX is to be removed on v11. This is to fix reconcilation # of the invoice with secondary_currency and the debit note without # secondary_currency secondary_currency = self.payment_group_id.to_pay_move_line_ids.mapped( 'currency_id') if len(secondary_currency) == 1: move_lines = invoice.move_id.line_ids.filtered( lambda x: x.account_id == invoice.account_id) # use _write because move is already posted if not move_lines.mapped('currency_id'): move_lines._write({ 'currency_id': secondary_currency.id, 'amount_currency': 0.0, }) self.payment_group_id.to_pay_move_line_ids += ( invoice.open_move_line_ids)
class sale_advance_payment_inv(models.TransientModel): _inherit = "sale.advance.payment.inv" @api.model def _get_invoice_currency_rate(self): sale_id = self._context.get('active_id', False) sale = self.env['sale.order'].browse(sale_id) return sale.pricelist_id.currency_id.compute( 1.0, sale.different_currency_id, round=True) @api.model def _get_invoice_currency_id(self): sale_id = self._context.get('active_id', False) return self.env['sale.order'].browse( sale_id).different_currency_id @api.model def _get_product_id(self): sale_id = self._context.get('active_id', False) return self.env['sale.order'].browse( sale_id).company_id.default_advance_product_id product_id = fields.Many2one( default=_get_product_id, ) invoice_currency_rate = fields.Float( 'Invoice Currency Rate', digits=(12, 6), default=_get_invoice_currency_rate, ) invoice_currency_id = fields.Many2one( 'res.currency', 'Invoice Currency', readonly=True, default=_get_invoice_currency_id, ) invoice_currency_amount = fields.Float( 'Invoice Currency Advance Amount', digits=dp.get_precision('Account'), compute='get_invoice_currency_amount', ) def onchange_method( self, cr, uid, ids, advance_payment_method, product_id, context=None): # Modificamos esta funcion para poder usar percentage con producto # y que no ponga el product en null if advance_payment_method == 'percentage': return {'value': {'amount': 0}} # return {'value': {'amount':0, 'product_id':False }} if product_id and advance_payment_method == 'fixed': product = self.pool.get('product.product').browse( cr, uid, product_id, context=context) return {'value': {'amount': product.list_price}} return {'value': {'amount': 0}} @api.multi def create_invoices(self): self.ensure_one() if self.advance_payment_method in ('lines'): raise Warning(_( "Configuration Error!\n" "If Invoice in different Currency you can not select " "'Percentage' or 'Some order lines'.")) return super(sale_advance_payment_inv, self).create_invoices() @api.depends('invoice_currency_rate', 'amount') def get_invoice_currency_amount(self): if self.invoice_currency_rate and self.amount: self.invoice_currency_amount = ( self.amount * self.invoice_currency_rate) def _prepare_advance_invoice_vals(self, cr, uid, ids, context=None): # Intento de heredar y modificar metodo # pero que era demasiado complicado # result = super(sale_advance_payment_inv, self)._prepare_advance_invoice_vals( # cr, uid, ids, context=context) # print 'context', context # print 'TODO Agregar el valor del campo de la otra currency' # return res # for invoice in result: # invoice_values = invoice[1] # print 'invoice_values', invoice_values # invoice_line_values = invoice[1]['invoice_line'] # print 'invoice_line_values', invoice_line_values # La simplificamos y sobreescribimos completamente if context is None: context = {} sale_obj = self.pool.get('sale.order') ir_property_obj = self.pool.get('ir.property') fiscal_obj = self.pool.get('account.fiscal.position') inv_line_obj = self.pool.get('account.invoice.line') wizard = self.browse(cr, uid, ids[0], context) sale_ids = context.get('active_ids', []) result = [] for sale in sale_obj.browse(cr, uid, sale_ids, context=context): val = inv_line_obj.product_id_change(cr, uid, [], wizard.product_id.id, False, partner_id=sale.partner_id.id, fposition_id=sale.fiscal_position.id, company_id=sale.company_id.id) res = val['value'] # determine and check income account if not wizard.product_id.id: prop = ir_property_obj.get(cr, uid, 'property_account_income_categ', 'product.category', context=context) prop_id = prop and prop.id or False account_id = fiscal_obj.map_account( cr, uid, sale.fiscal_position or False, prop_id) if not account_id: raise osv.except_osv(_('Configuration Error!'), _('There is no income account defined as global property.')) res['account_id'] = account_id if not res.get('account_id'): raise osv.except_osv(_('Configuration Error!'), _('There is no income account defined for this product: "%s" (id:%d).') % (wizard.product_id.name, wizard.product_id.id,)) # determine invoice amount if wizard.amount <= 0.00: raise osv.except_osv(_('Incorrect Data'), _('The value of Advance Amount must be positive.')) sale_currency_price_unit = False if wizard.advance_payment_method == 'percentage': # Esta es la parte que modificamos inv_amount = sale.amount_untaxed * wizard.amount / 100 if wizard.invoice_currency_id: sale_currency_price_unit = inv_amount inv_amount = inv_amount * wizard.invoice_currency_rate if not res.get('name'): res['name'] = _("Advance of %s %%") % (wizard.amount) else: # Esta es la parte que modificamos # inv_amount = wizard.amount if wizard.invoice_currency_id: inv_amount = wizard.invoice_currency_amount sale_currency_price_unit = wizard.amount else: inv_amount = wizard.amount if not res.get('name'): # TODO: should find a way to call formatLang() from # rml_parse symbol = sale.pricelist_id.currency_id.symbol if sale.pricelist_id.currency_id.position == 'after': res['name'] = _("Advance of %s %s") % ( inv_amount, symbol) else: res['name'] = _("Advance of %s %s") % ( symbol, inv_amount) # determine taxes if res.get('invoice_line_tax_id'): res['invoice_line_tax_id'] = [ (6, 0, res.get('invoice_line_tax_id'))] else: res['invoice_line_tax_id'] = False line_name = res.get('name') line_name += '. TC: %s' % wizard.invoice_currency_rate for line in sale.order_line: line_name += '\n* %s' % (line.name) # create the invoice inv_line_values = { 'name': line_name, 'origin': sale.name, 'account_id': res['account_id'], 'price_unit': inv_amount, 'sale_currency_price_unit': sale_currency_price_unit, 'quantity': wizard.qtty or 1.0, 'discount': False, 'uos_id': res.get('uos_id', False), 'product_id': wizard.product_id.id, 'invoice_line_tax_id': res.get('invoice_line_tax_id'), 'account_analytic_id': sale.project_id.id or False, 'sequence': 99, #las seteamos en 99 asi luego son copiadas con igual sequencia y van al final de todo } inv_values = { 'name': sale.client_order_ref or sale.name, 'origin': sale.name, 'type': 'out_invoice', 'reference': sale.client_order_ref or sale.name, 'account_id': sale.partner_id.property_account_receivable.id, 'partner_id': sale.partner_invoice_id.id, 'invoice_currency_rate': wizard.invoice_currency_rate, 'invoice_line': [(0, 0, inv_line_values)], # Aca tambien modificamos 'sale_currency_id': sale.pricelist_id.currency_id.id, 'currency_id': wizard.invoice_currency_id and wizard.invoice_currency_id.id or sale.pricelist_id.currency_id.id, 'comment': '', 'payment_term': sale.payment_term.id, 'fiscal_position': sale.fiscal_position.id or sale.partner_id.property_account_position.id } result.append((sale.id, inv_values)) return result
class WizStockPlanning(models.TransientModel): _name = 'wiz.stock.planning' _description = 'Wiz Stock Planning' @api.multi def _def_company(self): return self.env.user.company_id.id company = fields.Many2one('res.company', 'Company', default=_def_company, required=True) from_date = fields.Date( 'From date', required=True, help='Date from which the interval starts counting days') days = fields.Integer( 'Days interval', required=True, help='Increase number of days starting from the date from') to_date = fields.Date('To date', required=True, help='Deadline for calculating periods') category = fields.Many2one( 'product.category', 'Category', help='Enter this field if you want to filter by category') template = fields.Many2one( 'product.template', 'Template', help='Enter this field if you want to filter by template') product = fields.Many2one( 'product.product', 'Product', help='Enter this field if you want to filter by product') @api.multi def calculate_stock_planning(self): self.ensure_one() move_obj = self.env['stock.move'] procurement_obj = self.env['procurement.order'] planning_obj = self.env['stock.planning'] planning = planning_obj.search([]) planning.unlink() fdate = self.from_date from_date = False while fdate < self.to_date: product_datas = {} cond = [('company_id', '=', self.company.id), ('date', '<=', fdate), ('state', 'not in', ('done', 'cancel'))] if from_date: cond.append(('date', '>', from_date)) if self.product: cond.append(('product_id', '>', self.product_id.id)) moves = move_obj.search( cond).filtered(lambda x: x.location_id.usage == 'internal' or x .location_dest_id.usage == 'internal') if self.category: moves = moves.filtered(lambda x: x.product_id.product_tmpl_id. categ_id.id == self.category.id) if self.template: moves = moves.filtered(lambda x: x.product_id.product_tmpl_id. id == self.template.id) for move in moves: if move.location_id.usage == 'internal': product_datas = self._find_product_in_table( product_datas, move.product_id, move.location_id, move.warehouse_id) if move.location_dest_id.usage == 'internal': product_datas = self._find_product_in_table( product_datas, move.product_id, move.location_dest_id, move.warehouse_id) cond = [('company_id', '=', self.company.id), ('date_planned', '<=', fdate), ('state', 'in', ('confirmed', 'running'))] if from_date: cond.append(('date_planned', '>', from_date)) if self.product: cond.append(('product_id', '>', self.product_id.id)) procurements = procurement_obj.search(cond).filtered( lambda x: x.location_id.usage == 'internal') if self.category: procurements = procurements.filtered( lambda x: x.product_id.product_tmpl_id.categ_id.id == self. category.id) if self.template: procurements = procurements.filtered( lambda x: x.product_id.product_tmpl_id.id == self.template. id) for procurement in procurements: product_datas = self._find_product_in_table( product_datas, procurement.product_id, procurement.location_id, procurement.warehouse_id) for data in product_datas: datos_array = product_datas[data] vals = { 'company': self.company.id, 'location': datos_array['location'].id, 'scheduled_date': fdate, 'product': datos_array['product'].id } if from_date: vals['from_date'] = from_date if datos_array['warehouse']: vals['warehouse'] = datos_array['warehouse'].id else: cond = [('company_id', '=', self.company.id), ('lot_stock_id', '=', datos_array['location'].id)] warehouses = self.env['stock.warehouse'].search(cond) if warehouses: vals['warehouse'] = warehouses[0].id planning_obj.create(vals) from_date = fdate fdate = fields.Date.to_string( fields.Date.from_string(fdate) + relativedelta(days=self.days)) return { 'name': _('Stock Planning'), 'type': 'ir.actions.act_window', 'view_type': 'form', 'view_mode': 'tree', 'res_model': 'stock.planning', } def _find_product_in_table(self, product_datas, product, location, warehouse): found = False for data in product_datas: datos_array = product_datas[data] dproduct = datos_array['product'] dlocation = datos_array['location'] dwarehouse = datos_array['warehouse'] if dproduct.id == product.id and dlocation.id == location.id: found = True if not dwarehouse and warehouse: product_datas[data].update({'warehouse': warehouse}) break if not found: my_vals = { 'product': product, 'location': location, 'warehouse': warehouse, } ind = product.id + location.id + (warehouse.id or 0) product_datas[(ind)] = my_vals return product_datas