def create_payslip(self): payslips = self.env['hr.payslip'] for att_sheet in self: if att_sheet.payslip_id: new_payslip = att_sheet.payslip_id continue from_date = att_sheet.date_from to_date = att_sheet.date_to employee = att_sheet.employee_id slip_data = self.env['hr.payslip'].onchange_employee_id( from_date, to_date, employee.id, contract_id=False) contract_id = slip_data['value'].get('contract_id') if not contract_id: raise exceptions.Warning( 'There is No Contracts for %s That covers the period of the Attendance sheet' % employee.name) worked_days_line_ids = slip_data['value'].get( 'worked_days_line_ids') overtime = [{ 'name': "Overtime", 'code': 'OVT', 'contract_id': contract_id, 'sequence': 30, 'number_of_days': att_sheet.no_overtime, 'number_of_hours': att_sheet.tot_overtime, }] absence = [{ 'name': "Absence", 'code': 'ABS', 'contract_id': contract_id, 'sequence': 35, 'number_of_days': att_sheet.no_absence, 'number_of_hours': att_sheet.tot_absence, }] late = [{ 'name': "Late In", 'code': 'LATE', 'contract_id': contract_id, 'sequence': 40, 'number_of_days': att_sheet.no_late, 'number_of_hours': att_sheet.tot_late, }] difftime = [{ 'name': "Difference time", 'code': 'DIFFT', 'contract_id': contract_id, 'sequence': 45, 'number_of_days': att_sheet.no_difftime, 'number_of_hours': att_sheet.tot_difftime, }] worked_days_line_ids += overtime + late + absence + difftime # worked_days_line_ids += overtime + late + absence res = { 'employee_id': employee.id, 'name': slip_data['value'].get('name'), 'struct_id': slip_data['value'].get('struct_id'), 'contract_id': contract_id, 'input_line_ids': [(0, 0, x) for x in slip_data['value'].get('input_line_ids')], 'worked_days_line_ids': [(0, 0, x) for x in worked_days_line_ids], 'date_from': from_date, 'date_to': to_date, } print(res) new_payslip = self.env['hr.payslip'].create(res) att_sheet.payslip_id = new_payslip payslips += new_payslip #payslips.compute_sheet() return { 'type': 'ir.actions.act_window', 'res_model': 'hr.payslip', 'view_mode': 'form', 'view_type': 'form', 'res_id': new_payslip.id, 'views': [(False, 'form')], }
def _check_max_delta_days(self): if self.max_delta_days < 0: raise exceptions.Warning(_('Max delta days must be >= 0'))
def button_uninstall(self): for r in self: if r.name == MODULE_NAME and self.env.uid != SUPERUSER_ID: raise exceptions.Warning(_("Only admin can uninstall the module")) return super(Module, self).button_uninstall()
def do_count_tasks(self): Task = self.env['todo.task'] count = Task.search_count([('is_done', '=', False)]) raise exceptions.Warning('There are %d active tasks.' % count)
def import_product_pricelist(self): if self.import_option == 'csv': if (self.file): try: keys = [ 'product', 'pricelist', 'price', 'min_qty', 'start_dt', 'end_dt' ] csv_data = base64.b64decode(self.file) data_file = io.StringIO(csv_data.decode("utf-8")) data_file.seek(0) file_reader = [] csv_reader = csv.reader(data_file, delimiter=',') file_reader.extend(csv_reader) except Exception: raise exceptions.Warning(_("Invalid file!")) values = {} for i in range(len(file_reader)): field = list(map(str, file_reader[i])) values = dict(zip(keys, field)) if values: if i == 0: continue else: values.update({'option': self.import_option}) res = self.make_product_pricelist(values) else: raise Warning(_('Please Seelect a file.')) else: if (self.file): try: fp = tempfile.NamedTemporaryFile(delete=False, suffix=".xlsx") fp.write(binascii.a2b_base64(self.file)) fp.seek(0) values = {} workbook = xlrd.open_workbook(fp.name) sheet = workbook.sheet_by_index(0) except Exception: raise exceptions.Warning(_("Invalid file!")) for row_no in range(sheet.nrows): val = {} if row_no <= 0: fields = map(lambda row: row.value.encode('utf-8'), sheet.row(row_no)) else: line = list( map( lambda row: isinstance(row.value, bytes) and row.value.encode('utf-8') or str(row.value), sheet.row(row_no))) start_date_string = False end_dt_string = False if line[4] and line[5]: start_dt = int(float(line[4])) end_dt = int(float(line[5])) start_dt_datetime = datetime(*xlrd.xldate_as_tuple( start_dt, workbook.datemode)) end_dt_datetime = datetime(*xlrd.xldate_as_tuple( end_dt, workbook.datemode)) start_date_string = start_dt_datetime.date( ).strftime('%Y-%m-%d') end_dt_string = end_dt_datetime.date().strftime( '%Y-%m-%d') min_qty = 1 if line[3]: min_qty = int(float(line[3])) values.update({ 'product': line[0], 'pricelist': line[1], 'price': line[2], 'min_qty': min_qty, 'start_dt': start_date_string, 'end_dt': end_dt_string, }) res = self.make_product_pricelist(values) else: raise Warning(_('Please Seelect a file.'))
def check_date(self): if self.start_date > self.end_date: raise exceptions.Warning( _('Error!:: End date is lower than start date.'))
def unlink(self): if self.mapped('purchase_lines'): raise exceptions.Warning( _('You cannot delete a record that refers to purchase ' 'lines!')) return super(PurchaseRequestLine, self).unlink()
def _get_export_for_l10n_si_tax_reg_taxes_value_calculated(self, data): res = {} rec = {} tmp = {} ResPartner = self.env['res.partner'] precision = dp.get_precision('Account')(self.env.cr)[1] if precision > 2: _logger.warning(_('Slovenian tax registry does not support decimal value rounding larger than 2 digits.')) # _logger.info('\n*---------\n' # '*DATA: %s\n' # '*------------\n', data) for d in data: # _logger.info('\n*---------\n' # '*DATA PART: %s\n' # '*------------\n', d) if 'account_tax_ids' not in d or not d['account_tax_ids']: continue for t in d['account_tax_ids']: if t.id in rec: continue if _ODOO_TAX_TYPE_2_SI_TAX_TYPE[t.l10n_si_tax_reg_tax_type][1] and t.amount_type != 'percent': raise exceptions.Warning(_('Slovenian tax registry supports only percent-based calculation on certain taxes.')) # rec[t.id] = (t.l10n_si_tax_reg_tax_type, float_round(t.amount * 100, precision_digits=precision)) # amount in Odoo 8 is 0.22 for 22% in Odoo 9 is 22 for 22% rec[t.id] = (t.l10n_si_tax_reg_tax_type, float_round(t.amount, precision_digits=precision)) # _logger.info('\n*---------\n' # '*TAX DICT: %s\n' # '*---------\n', rec) # TODO: Set correct currency taxes = d['account_tax_ids'].compute_all(d['price'], quantity=d['qty'], product=d['product_id'] or None, partner=d['partner_id'] and ResPartner.browse(d['partner_id']) or None) # _logger.info('\n*---------\n' # '*TAXES: %s\n' # '*---------\n', taxes) # XXX: Written poorly. Make a better rewrite. for t in taxes['taxes']: type = _ODOO_TAX_TYPE_2_SI_TAX_TYPE[rec[t['id']][0]] if type[0] not in tmp: tmp[type[0]] = {} if type[1] else 0.0 if type[1]: if rec[t['id']][1] not in tmp[type[0]]: tmp[type[0]][rec[t['id']][1]] = [0.0, 0.0, type[1][0], type[1][1], type[1][2]] tmp[type[0]][rec[t['id']][1]][0] += float('.'.join(str(float_round(d['qty'] * d['price'], precision_digits=precision)).split('.'))) tmp[type[0]][rec[t['id']][1]][1] += t['amount'] else: tmp[type[0]][rec[t['id']][1]] += t['amount'] for k, t in tmp.iteritems(): if isinstance(t, dict): res[k] = [] for m, d in t.iteritems(): res[k].append({ d[2]: m, d[3]: float('.'.join(str(float_round(d[0], precision_digits=precision)).split('.'))), d[4]: float('.'.join(str(float_round(d[1], precision_digits=precision)).split('.'))), }) else: res[k] = float('.'.join(str(float_round(t, precision_digits=precision)).split('.'))) return res
def update_method(self): if self.integration_id.method_id.code == 'demo': self.state = 'sent' self.update_date = datetime.now() return raise exceptions.Warning(_('No update method has been created'))
def l10n_si_tax_reg_reexecute(self): if not self.l10n_si_tax_reg_sent or self.l10n_si_tax_reg_eor: raise exceptions.Warning(_('Cannot send registration request on finished or new invoices.')) return self.l10n_si_tax_reg_execute()
def _l10n_si_tax_reg_execute_auto_paid(self): if not self.l10n_si_tax_reg_premise_line_id or not self.l10n_si_tax_reg_premise_line_id.invoice_registered: return True if not self._get_l10n_si_tax_reg_paid_state(): raise exceptions.Warning(_('Invoice not in paid state.')) return self.l10n_si_tax_reg_execute()
def unlink(self): if any(i.l10n_si_tax_reg_sent for i in self): raise exceptions.Warning(_('You cannot delete an invoice which has already been registered at FURS. You should refund it instead.')) return super(L10nSiTaxRegInterface, self).unlink()
def import_product_order(self): product_main_obj = self.env['product.product'] file_data = False if self.select_file and self.data_file: if self.select_file == 'csv': csv_reader_data = pycompat.csv_reader(io.BytesIO(base64.decodestring(self.data_file)), quotechar="," ,delimiter=",") csv_reader_data = iter(csv_reader_data) next(csv_reader_data) file_data = csv_reader_data elif self.select_file == 'xls': file_datas = base64.decodestring(self.data_file) workbook = xlrd.open_workbook(file_contents=file_datas) sheet = workbook.sheet_by_index(0) result = [] data = [[sheet.cell_value(r, c) for c in range(sheet.ncols)] for r in range(sheet.nrows)] data.pop(0) file_data = data else: raise exceptions.Warning(_('Please select file and type of file or picking type')) for row in file_data: tax_list = [] if self.select_file == 'csv' and len(row) != 14: raise ValidationError("You can let empty cell in csv file or please use xls file.") if row[0] == "" or row[3] == "": raise ValidationError("Please Assign The Product Name And Type.") search_product = product_main_obj.search([('name','=',row[0] or "_____________")]) uom_ids = self.env['product.uom'].search([('name', '=', row[5] or "_____________")]) uom_po_ids = self.env['product.uom'].search([('name', '=', row[6] or "_____________")]) tax_id = self.env['account.tax'].search([('name', '=', row[15] or "_____________")]) tax_list.append(tax_id.id) if not uom_ids: raise ValidationError("Uom ids '%s' is not founded" % row[5]) if not uom_po_ids: raise ValidationError("Purchase Uom ids '%s' is not founded" % row[6]) categ_id_ids = self.env['product.category'].search([('name','=',row[2] or "_____________")]) if not categ_id_ids: raise ValidationError("categ_ids '%s' is not founded" % row[2]) if not tax_id: raise ValidationError("Tax id '%s' is not founded" % row[15]) product_obj = self.env['product.product'] product_fields = product_obj.fields_get() pro_def_val = product_obj.default_get(product_fields) new_pro_up = pro_def_val.copy() if row[4] != "" : new_pro_up.update({ 'name': row[0], 'default_code': row[1] or "", 'type' : row[3], 'list_price': row[7] or "", 'standard_price': row[8] or "", 'categ_id': categ_id_ids.id, 'uom_id' : uom_ids.id, 'uom_po_id' : uom_po_ids.id, 'weight' : row[9] != "" and float(row[9]) or "", 'volume' : row[10] != "" and float(row[10]) or "", 'barcode' : row[4] != "" and row[4] or "", 'taxes_id' : [( 6, 0, tax_list)], # 'latin_name': row[14] or "", }) elif row[4] == "" : new_pro_up.update({ 'name': row[0], 'default_code': row[1] or "", 'type' : row[3], 'list_price': row[7] or "", 'standard_price': row[8] or "", 'categ_id': categ_id_ids.id, 'uom_id' : uom_ids.id, 'uom_po_id' : uom_po_ids.id, 'weight' : row[9] != "" and float(row[9]) or "", 'volume' : row[10] != "" and float(row[10]) or "", 'taxes_id' : [( 6, 0, tax_list)], # 'latin_name': row[14] or "", }) if search_product: product_created_id = search_product.write(new_pro_up) if search_product.type in ['product'] and row[11] != '' and row[12] != '': product = self.env['product.product'].search([('name', '=', row[0] or "_____________")]) stock_location = self.env['stock.location'].search([('id', '=', int(row[12]) or "_____________")]) if not stock_location: raise ValidationError("Stock Location '%s' is not founded" % row[12]) if row[13] == '': self.env['stock.quant']._update_available_quantity(product, stock_location, float(row[11])) elif row[13] != '': lot = self.env['stock.production.lot'].search([('id', '=', int(row[13]) or "_____________")]) if not lot: raise ValidationError("Production Lot id '%s' is not founded" % row[13]) self.env['stock.quant']._update_available_quantity(product, stock_location, float(row[11]),lot_id=lot) else: product_created_id = product_main_obj.create(new_pro_up) if product_created_id.type in ['product'] and row[11] != '' and row[12] != '': product = self.env['product.product'].search([('name', '=', row[0] or "_____________")]) stock_location = self.env['stock.location'].search([('id', '=', int(row[12]) or "_____________")]) if not stock_location: raise ValidationError("Stock Location '%s' is not founded" % row[12]) if row[13] == '': self.env['stock.quant']._update_available_quantity(product, stock_location, float(row[11])) elif row[13] != '': lot = self.env['stock.production.lot'].search([('id', '=', int(row[13]) or "_____________")]) if not lot: raise ValidationError("Production Lot id '%s' is not founded" % row[13]) self.env['stock.quant']._update_available_quantity(product, stock_location, float(row[11]),lot_id=lot)
def set_busy_icon_status(self, uid, location_alias, operation, busy_types): ''' 设置轨道占线板信息 :return: ''' raise exceptions.Warning('没有实现set_busy_icon_status, 请在线别中去实此函数!')
def check_redsys_percent_partial(self): if self.redsys_percent_partial < 0 or self.redsys_percent_partial > 100: raise exceptions.Warning( _("Partial payment percent must be between 0 and 100") )
def import_delivery_picking(self): """ Import sale order line selected where q. is present """ move_pool = self.env['stock.move'] quant_pool = self.env['stock.quant'] picking_pool = self.env['stock.picking'] # Sale order detail: sale_line_pool = self.env['sale.order.line'] # Purchase order detail: # purchase_pool = self.env['purchase.order'] line_pool = self.env['purchase.order.line'] # Partner: partner_pool = self.env['res.partner'] # now = fields.Datetime.now() gap = 0.000001 # For approx quantity check # --------------------------------------------------------------------- # Save passed file: # --------------------------------------------------------------------- b64_file = base64.decodebytes(self.file) now = ('%s' % fields.Datetime.now())[:19] filename = '/tmp/stock_%s.xlsx' % \ now.replace(':', '_').replace('-', '_') f = open(filename, 'wb') f.write(b64_file) f.close() # --------------------------------------------------------------------- # Open Excel file: # --------------------------------------------------------------------- try: wb = xlrd.open_workbook(filename) except: raise exceptions.Warning(_('Cannot read XLS file')) ws = wb.sheet_by_index(0) # Check sheet mode: sheet_mode = ws.cell_value(0, 0) company = self.env.user.company_id title_counter = company.purchase_export_ref if not title_counter: raise exceptions.Warning( 'Wrong Excel file mode, last was yet imported') if sheet_mode != title_counter: raise exceptions.Warning( 'Wrong Excel file mode, expected: %s, got: %s' % (title_counter, sheet_mode)) company.purchase_export_ref = False # Clean when imported # --------------------------------------------------------------------- # Load parameters: # --------------------------------------------------------------------- company = self.env.user.company_id location_id = company.logistic_location_id.id logistic_pick_in_type = company.logistic_pick_in_type_id logistic_pick_in_type_id = logistic_pick_in_type.id location_from = logistic_pick_in_type.default_location_src_id.id location_to = logistic_pick_in_type.default_location_dest_id.id # Store for manage after Excel loop: picking_data = {} # arrived data from supplier (key was supplier) internal_data = [] # extra data from supplier order_touched = [] # For end operation (dropship, default suppl.) log = { 'error': [], 'warning': [], 'info': [], } start_import = False # Read and stock in dict data information: for row in range(ws.nrows): line_ref = ws.cell_value(row, self._column_position['id']) if not start_import and line_ref == 'ID': start_import = True _logger.info('%s. Header line' % row) continue if not start_import: _logger.info('%s. Jump line' % row) continue # A. Check ID line line_ids = [int(line_id) for line_id in line_ref.split('|')] if not line_ids: log['error'].append(_('%s. No ID for this line') % row) continue lines = line_pool.browse(line_ids) if not lines: log['error'].append( _('%s. No lined found with ID: %s') % (row, line_ids)) continue # Extract needed data: supplier_id = ws.cell_value(row, self._column_position['supplier_id']) supplier_price = ws.cell_value( row, self._column_position['supplier_price']) or 0.0 all_qty = ws.cell_value(row, self._column_position['all_qty']) if all_qty: # Manage not delivered to client arrived_qty = sum([l.logistic_undelivered_qty for l in lines]) else: arrived_qty = ws.cell_value( row, self._column_position['arrived_qty']) or 0.0 # ------------------------------------------------------------- # Check if arrived is present: # ------------------------------------------------------------- if not arrived_qty: log['info'].append(_('%s. No qty, line not imported') % row) continue # ------------------------------------------------------------- # A. Check supplier data # ------------------------------------------------------------- if not supplier_id: log['error'].append(_('%s. No ID for supplier') % row) continue supplier_id = int(supplier_id) suppliers = partner_pool.search([('id', '=', supplier_id)]) if not suppliers: log['error'].append( _('%s. No supplier found with ID: %s') % (row, supplier_id)) continue supplier = suppliers[0] if not supplier_price: log['warning'].append( _('%s. No purchase price but qty present') % row) # continue # TODO convert in error? lines = sorted( lines, # Before linked order create first after internal stock: key=lambda l: (not l.logistic_sale_id, l.create_date), ) for line in lines: if not arrived_qty: # Nothing remain break # Not read reload from DB remain to delivery (waiting): logistic_sale_id = line.logistic_sale_id # Linked sale order! undelivered_qty = line.logistic_undelivered_qty # Extract used qty for this line: if undelivered_qty <= arrived_qty: used_qty = undelivered_qty else: used_qty = arrived_qty if used_qty < 0: continue arrived_qty -= used_qty # ------------------------------------------------------------- # Populate data for next job: # ------------------------------------------------------------- if supplier not in picking_data: picking_data[supplier] = [] # Always create stock move: log['info'].append(_('%s. Delivery for sale order') % row) # Purchase / picking data: picking_data[supplier].append( (line, used_qty, supplier_price, False)) if not logistic_sale_id: # Quants data (goes also in internal) internal_data.append( (supplier, line, used_qty, supplier_price)) # For final logistic state update if line.order_id not in order_touched: # Purchase Order order_touched.append(line.order_id) # ----------------------------------------------------------------- # Extra goes in internal stock: # ----------------------------------------------------------------- if arrived_qty > 0: # line was last line of the list (extra will be attached here) # NOTE: always present: picking_data[supplier].append( (line, arrived_qty, supplier_price, True)) internal_data.append( (supplier, line, arrived_qty, supplier_price)) # ===================================================================== # Final Stock operations: # ===================================================================== # A. Internal stock: # ------------------ for supplier, line, internal_qty, supplier_price in internal_data: product = line.product_id data = { 'company_id': company.id, 'in_date': now, 'location_id': location_id, 'product_id': product.id, 'quantity': internal_qty, # Link: 'logistic_purchase_id': line.id, # 'logistic_assigned_id': line.id, # Link field # 'product_tmpl_id': used_product.product_tmpl_id.id, # 'lot_id' # 'package_id' } try: quant_pool.create(data) except: raise exceptions.Warning('Cannot create quants!') # ---------------------- # B. Load purchased line # ---------------------- sale_lines = [] # To check status for supplier in picking_data: # Readability data: now = '{}'.format(fields.Datetime.now())[:10] origin = 'Del. {}'.format(now) # ----------------------------------------------------------------- # Create new picking: # ----------------------------------------------------------------- picking = picking_pool.create({ 'partner_id': supplier.id, 'scheduled_date': now, 'origin': origin, # 'move_type': 'direct', 'picking_type_id': logistic_pick_in_type_id, 'group_id': False, 'location_id': location_id, 'location_dest_id': location_to, # 'priority': 1, 'state': 'done', # immediately! }) # ----------------------------------------------------------------- # Append stock.move detail # ----------------------------------------------------------------- for record in picking_data[supplier]: # Readability data: line, arrived_qty, supplier_price, go_internal = record product = line.product_id if go_internal: sale_line_id = False else: sale_line_id = line.logistic_sale_id.id if sale_line_id: # Update status at the end sale_lines.append(line.logistic_sale_id) origin = line.order_id.name # ------------------------------------------------------------- # Create movement (not load stock): # ------------------------------------------------------------- move_pool.create({ 'company_id': company.id, 'partner_id': supplier.id, 'picking_id': picking.id, 'product_id': product.id, 'name': product.name or ' ', 'date': now, 'date_expected': now, 'location_id': location_id, 'location_dest_id': location_to, 'product_uom_qty': arrived_qty, 'product_uom': product.uom_id.id, 'state': 'done', 'origin': origin, # Sale order line link: 'logistic_load_id': sale_line_id, # Purchase order line line: 'logistic_purchase_id': line.id, # 'purchase_line_id': load_line.id, # XXX needed? # 'logistic_quant_id': quant.id, # XXX no quants here # group_id # reference' # sale_line_id # procure_method, # 'product_qty': select_qty, }) # ----------------------------------------------------------------- # Update logistic status: Sale order # ----------------------------------------------------------------- # Mark Sale Order Line ready: _logger.info('Update sale order line as ready:') orders = [] for order_line in sale_lines: order = order_line.order_id if order not in orders: orders.append(order) # Reload line to check remain awaiting: if sale_line_pool.browse( order_line.id).logistic_remain_qty <= gap: order_line.write({ 'logistic_state': 'ready', }) all_ready = {'ready'} for order in orders: # TODO reload? states = set( [line.logistic_state for line in order.order_line]) if states == all_ready: order.write({'logistic_state': 'ready'}) # ----------------------------------------------------------------- # Check Purchase order ready # ----------------------------------------------------------------- _logger.info('Check purchase order closed:') for purchase in order_touched: for po_line in purchase.order_line: if po_line.logistic_undelivered_qty > 0: break else: # If exit without break >> all delivered! purchase.write({ 'logistic_state': 'done', })
def unlink(self): for channel in self: if channel.name == 'root': raise exceptions.Warning(_('Cannot remove the root channel')) return super(JobChannel, self).unlink()
def compute_pricelist(self): # Se obtiene la fecha actual current_date = datetime.now().date() #current_date = current_date + relativedelta(days=3) #Se obtiene el objeto donde se almacena el registro de cada ejecucion for record in self: #se obtiene el tipo de cambio del dia r_today = self.env['marvel.currency'].search([ ('currency_date', '>=', current_date), ('currency_date', '<=', current_date) ]) #si ya existe un tipo de cambio de el dia Actualiza el precio de lista de los productos if r_today: factor_today = 1 for rate_t in r_today: factor_today = rate_t.factor #se obtienen las categorias a actualizar Categories_to_update = self.env['marvel.category'].search([ ('active', '=', True) ]) if not Categories_to_update: raise exceptions.Warning( _('There isn\'t Categories to update on Marvel\'s Pricelist! \n Please add some Categories to update it\'s Prices!' )) #se obtienen los productos correspondientes a las categorias products = self.env['product.product'] for c in Categories_to_update: #print("Categories = " + str(c.category_name.display_name)) products += self.env['product.product'].search([ ('categ_id.complete_name', '=', c.category_name.display_name) ]) products += self.env['product.product'].search([ ('categ_id.parent_id.complete_name', '=', c.category_name.display_name) ]) #print('Products inicial = '+ str(products)) #Revisamos si existen ejecuciones anteriores exitosas excecution = self.env['marvel.pricelist'].search([ ('successful', '=', True) ]) #si hay ejecuciones exitosas anteriores ya existe un tipo de cambio anterior if excecution: #busca si ya tiene ejecuciones el dia de hoy excecution_today = excecution.search([ ('excecution_date', '>=', current_date), ('excecution_date', '<=', current_date) ]) if excecution_today: excecution_list = [ date for date in excecution_today.mapped( 'excecution_date') if date ] last_excecution_date = excecution_list and max( excecution_list) last_excecution = self.env['marvel.pricelist'].search([ ('excecution_date', '=', last_excecution_date) ]) if "{0:.8}".format(last_excecution.factor ) != "{0:.8}".format(factor_today): #Actualizamos el precio de lista de los productos for product in products: pricelist_base = product.list_price / last_excecution.factor new_price = pricelist_base * factor_today #print('old price = ' + str(product.list_price)) #print('base price = ' + str(pricelist_base)) #print('new price = ' + str(new_price)) prod_value = {'list_price': new_price} product.write(prod_value) #almacenamos la ejecucion como exitosa excecution_values = { 'excecution_date': datetime.now(), 'exchange_rate': rate_t.rate_today, 'factor': factor_today, 'successful': True, } self.write(excecution_values) return { 'effect': { 'fadeout': 'slow', 'message': "Yeah! The prices of the products were calculated and updated", 'img_url': '/web/static/src/img/smile.svg', 'type': 'rainbow_man', } } else: #print('no actualiza nada por que el tipo de cambio es el mismo') #almacenamos la ejecucion como exitosa excecution_values = { 'excecution_date': datetime.now(), 'exchange_rate': rate_t.rate_today, 'factor': factor_today, 'successful': True, } self.write(excecution_values) raise exceptions.Warning( _('Marvel\'s exchange rate is already updated with today\'s exchange rate! \n It is not necessary to update the data again.' )) else: #print('entro a guardar la nueva ejecucion del dia de hoy') #se obtiene la ultima ejecucion exitosa excecution_list = [ date for date in excecution.mapped('excecution_date') if date ] last_excecution_date = excecution_list and max( excecution_list) last_excecution = self.env['marvel.pricelist'].search([ ('excecution_date', '=', last_excecution_date) ]) #Actualizamos los Productos for product in products: pricelist_base = product.list_price / last_excecution.factor new_price = pricelist_base * factor_today #print('old price = ' + str(product.list_price)) #print('base price = ' + str(pricelist_base)) #print('new price = ' + str(new_price)) prod_value = {'list_price': new_price} product.write(prod_value) #almacenamos la ejecucion como exitosa excecution_values = { 'excecution_date': datetime.now(), 'exchange_rate': rate_t.rate_today, 'factor': factor_today, 'successful': True, } self.write(excecution_values) return { 'effect': { 'fadeout': 'slow', 'message': "Yeah! The prices of the products were calculated and updated", 'img_url': '/web/static/src/img/smile.svg', 'type': 'rainbow_man', } } #no existe una ejecucion exitosa por lo tanto es la primera vez que se ejecuta else: #print('entro a la ejecucion por primera vez') #Actualizamos los Productos #print('factor today = ' + str(factor_today)) #print('products = ' + str(products)) for product in products: pricelist_base = product.list_price new_price = pricelist_base * factor_today #print('old price = ' + str(product.list_price)) #print('base price = ' + str(pricelist_base)) #print('new price = ' + str(new_price)) prod_value = {'list_price': new_price} product.write(prod_value) #almacenamos la ejecucion como exitosa excecution_values = { 'excecution_date': datetime.now(), 'exchange_rate': rate_t.rate_today, 'factor': factor_today, 'successful': True, } self.write(excecution_values) return { 'effect': { 'fadeout': 'slow', 'message': "Yeah! The prices of the products were calculated and updated", 'img_url': '/web/static/src/img/smile.svg', 'type': 'rainbow_man', } } # Si no existe tipo de cambio se almacena la ejecucion en Falso else: excecution_values = { 'excecution_date': datetime.now(), #'exchange_rate': rate_t.rate_today, #'factor': factor_today, 'successful': False, } raise exceptions.Warning( _('Marvel\'s exchange rate doesn\'t have a Exchange rate registered for today! \n Please request the update to the corresponding department!' )) self.write(excecution_values)
def import_image(self): try: fp = tempfile.NamedTemporaryFile(delete=False, suffix=".xlsx") fp.write(binascii.a2b_base64(self.file)) fp.seek(0) values = {} workbook = xlrd.open_workbook(fp.name) sheet = workbook.sheet_by_index(0) except Exception: raise exceptions.Warning( _("Please select an CSV/XLS file or You have selected invalid file" )) for row_no in range(sheet.nrows): val = {} if row_no <= 0: fields = map(lambda row: row.value.encode('utf-8'), sheet.row(row_no)) else: line = list( map( lambda row: isinstance(row.value, bytes) and row.value. encode('utf-8') or str(row.value), sheet.row(row_no))) if self.operation == 'update' and self.update_by == 'id': if not line[0]: raise Warning(_(' ID does not found in Excel')) values.update({ 'id': int(float(line[0])), 'image_1920': line[1], }) if values.get('image_1920') != '': try: with open(values.get('image'), "rb") as image_file: f = base64.b64encode(image_file.read()) except: f = False else: f = False elif self.operation == 'update' and self.update_by == 'name': if not line[0]: raise Warning(_(' Name does not found in Excel')) values.update({ 'name': line[0], 'image_1920': line[1], }) if values.get('image_1920') != '': try: with open(values.get('image'), "rb") as image_file: f = base64.b64encode(image_file.read()) except: f = False else: f = False elif self.operation == 'update' and self.update_by == 'code': if not line[0]: raise Warning(_(' Code does not found in Excel')) values.update({ 'code': line[0], 'image_1920': line[1], }) if values.get('image_1920') != '': try: with open(values.get('image'), "rb") as image_file: f = base64.b64encode(image_file.read()) except: f = False else: f = False elif self.operation == 'create': if not line[0]: raise Warning(_(' Name not found in Excel')) values.update({ 'code': line[1], 'name': line[0], 'image_1920': line[2], 'image_1920_small': line[2], }) if values.get('image_1920') != '': try: with open(values.get('image'), "rb") as image_file: f = base64.b64encode(image_file.read()) except: f = False else: f = False if self.model == 'template': model = self.env['product.template'] else: model = self.env['product.product'] if self.operation == 'create': model.create({ 'name': values.get('name'), 'default_code': values.get('code'), 'image_1920': f }) else: if self.update_by == 'id': if not values.get('id'): raise Warning(_('ID does not found in Excel')) else: prod_search = model.search([('id', '=', values.get('id'))]) elif self.update_by == 'name': if not values.get('name'): raise Warning(_('Name does not found in Excel')) else: prod_search = model.search([('name', '=', values.get('name'))]) elif self.update_by == 'code': if not values.get('code'): raise Warning( _('Code("Internal Reference ") does not found in Excel' )) else: prod_search = model.search([('default_code', '=', values.get('code'))]) if prod_search: for product in prod_search: product.image_1920 = f product.image_small = f else: raise Warning( _('"%s" does not found') % values.get('name')) return True
def onchange_date(self): if str(self.fechatermino) < str(self.fechainicio): raise exceptions.Warning('No se puede seleccionar una Fecha anterior a la actual, ' 'por favor seleccione una fecha actual o posterior') else: return False
def import_sale(self): if self.file_name.split('.')[-1] not in ['xls','csv']: raise Warning(_('Import File should be csv or xls')) obj = self.env[self.env.context.get('active_model', False)].browse(self.env.context.get('active_ids', False)) data = base64.b64decode(self.import_file) final_data = [] if self.file_name.split('.')[-1] == 'csv': file_input = cStringIO.StringIO(data) file_input.seek(0) reader = csv.reader(file_input, delimiter=',',lineterminator='\r\n') reader_info = [] try: reader_info.extend(reader) except Exception: raise exceptions.Warning(_("Not a valid file!")) for i in range(1, len(reader_info)): try: field = map(str, reader_info[i]) except ValueError: raise exceptions.Warning(_("Dont Use Charecter only use numbers")) if field[1]: product_ids = self.env['product.product'].search([('name', '=', field[1].strip())]) if product_ids: product_id = product_ids.filtered( lambda record: (record.default_code or '') == field[0].strip() or '') if product_id and len(product_id) == 1: if self.env.context.get('active_model', False) and self.env.context.get('active_ids',False): obj = self.env[self.env.context.get('active_model', False)].browse(self.env.context.get('active_ids', False)) line_data = [0, 0, { 'product_id': product_id.id, 'price_unit': float(field[3]) or 0, 'product_uom_qty': float(field[2]) or 0, 'part_name' : product_id.part_name or '', }] if self.env.context.get('active_model', False) == 'sale.order': line_data[2].update({'product_uom': product_id.uom_id.id or False,}) elif self.env.context.get('active_model', False) == 'sale.requisition': line_data[2].update({'product_uom_id': product_id.uom_id.id or False, 'part_number_mitsuyoshi' : product_id.default_code or '', 'customer_pmb_no' : product_id.customer_pmb_no or '', }) final_data.append(line_data) elif self.file_name.split('.')[-1] == 'xls': wb = open_workbook(file_contents=data) sheet = wb.sheet_by_index(0) count = 0 error = 0 for row_no in range(sheet.nrows): val = {} if row_no <= 0: header = ( map(lambda row: isinstance(row.value, unicode) and row.value.encode('utf-8') or str(row.value), sheet.row(row_no))) else: row = ( map(lambda row: isinstance(row.value, unicode) and row.value.encode('utf-8') or str(row.value), sheet.row(row_no))) product_ids = [] if row[1]: product_ids = self.env['product.product'].search([('name','=',row[1].strip())]) if product_ids: product_id = product_ids.filtered(lambda record:(record.default_code or '') == row[0].strip() or '') if product_id and len(product_id) == 1: if self.env.context.get('active_model',False) and self.env.context.get('active_ids',False): obj = self.env[self.env.context.get('active_model',False)].browse(self.env.context.get('active_ids',False)) line_data = [0,0,{ 'product_id' : product_id.id, 'price_unit' : float(row[3]) or 0, 'product_uom_qty': float(row[2]) or 0, 'part_name' : product_id.part_name or '', }] if self.env.context.get('active_model', False) == 'sale.order': line_data[2].update({'product_uom': product_id.uom_id.id or False}) elif self.env.context.get('active_model', False) == 'sale.requisition': line_data[2].update({'product_uom_id': product_id.uom_id.id or False, 'part_number_mitsuyoshi': product_id.default_code or '', 'customer_pmb_no': product_id.customer_pmb_no or '', }) final_data.append(line_data) else: error += 1 if self.env.context.get('active_model', False) == 'sale.order': obj.write({'order_line' : final_data}) elif self.env.context.get('active_model',False) == 'sale.requisition': obj.write({'line_ids': final_data}) action = self.env['ir.actions.act_window'].browse(self.env.context.get('params',False).get('action',False)) action['res_id'] = obj.id return action
def _get_lines(self, dispatchmode=False, extendedmode=False): company = self.company_id IntrastatRegion = self.env['l10n_be_intrastat.region'] if dispatchmode: mode1 = 'out_invoice' mode2 = 'in_refund' declcode = "29" else: mode1 = 'in_invoice' mode2 = 'out_refund' declcode = "19" decl = ET.Element('Report') if not extendedmode: decl.set('code', 'EX%sS' % declcode) else: decl.set('code', 'EX%sE' % declcode) decl.set('date', '%s-%s' % (self.year, self.month)) datas = ET.SubElement(decl, 'Data') if not extendedmode: datas.set('form', 'EXF%sS' % declcode) else: datas.set('form', 'EXF%sE' % declcode) datas.set('close', 'true') intrastatkey = namedtuple( "intrastatkey", ['EXTRF', 'EXCNT', 'EXTTA', 'EXREG', 'EXGO', 'EXTPC', 'EXDELTRM']) entries = {} query = """ SELECT inv_line.id FROM account_invoice_line inv_line JOIN account_invoice inv ON inv_line.invoice_id=inv.id LEFT JOIN res_country ON res_country.id = inv.intrastat_country_id LEFT JOIN res_partner ON res_partner.id = inv.partner_id LEFT JOIN res_country countrypartner ON countrypartner.id = res_partner.country_id JOIN product_product ON inv_line.product_id=product_product.id JOIN product_template ON product_product.product_tmpl_id=product_template.id WHERE inv.state IN ('open','paid') AND inv.company_id=%s AND not product_template.type='service' AND (res_country.intrastat=true OR (inv.intrastat_country_id is NULL AND countrypartner.intrastat=true)) AND ((res_country.code IS NOT NULL AND not res_country.code=%s) OR (res_country.code is NULL AND countrypartner.code IS NOT NULL AND not countrypartner.code=%s)) AND inv.type IN (%s, %s) AND to_char(inv.date_invoice, 'YYYY')=%s AND to_char(inv.date_invoice, 'MM')=%s """ self.env.cr.execute(query, (company.id, company.partner_id.country_id.code, company.partner_id.country_id.code, mode1, mode2, self.year, self.month)) lines = self.env.cr.fetchall() invoicelines_ids = [rec[0] for rec in lines] invoicelines = self.env['account.invoice.line'].browse( invoicelines_ids) for inv_line in invoicelines: #Check type of transaction if inv_line.intrastat_transaction_id: extta = inv_line.intrastat_transaction_id.code else: extta = "1" #Check country if inv_line.invoice_id.intrastat_country_id: excnt = inv_line.invoice_id.intrastat_country_id.code else: excnt = inv_line.invoice_id.partner_shipping_id.country_id.code or inv_line.invoice_id.partner_id.country_id.code #Check region #If purchase, comes from purchase order, linked to a location, #which is linked to the warehouse #if sales, the sales order is linked to the warehouse #if sales, from a delivery order, linked to a location, #which is linked to the warehouse #If none found, get the company one. exreg = None if inv_line.invoice_id.type in ('in_invoice', 'in_refund'): #comes from purchase po_lines = self.env['purchase.order.line'].search( [('invoice_lines', 'in', inv_line.id)], limit=1) if po_lines: if self._is_situation_triangular(company, po_line=po_lines): continue location = self.env['stock.location'].browse( po_lines.order_id._get_destination_location()) region_id = self.env[ 'stock.warehouse'].get_regionid_from_locationid( location) if region_id: exreg = IntrastatRegion.browse(region_id).code elif inv_line.invoice_id.type in ('out_invoice', 'out_refund'): #comes from sales so_lines = self.env['sale.order.line'].search( [('invoice_lines', 'in', inv_line.id)], limit=1) if so_lines: if self._is_situation_triangular(company, so_line=so_lines): continue saleorder = so_lines.order_id if saleorder and saleorder.warehouse_id and saleorder.warehouse_id.region_id: exreg = IntrastatRegion.browse( saleorder.warehouse_id.region_id.id).code if not exreg: if company.region_id: exreg = company.region_id.code else: self._company_warning( _('The Intrastat Region of the selected company is not set, ' 'please make sure to configure it first.')) #Check commodity codes intrastat_id = inv_line.product_id.get_intrastat_recursively() if intrastat_id: exgo = self.env['report.intrastat.code'].browse( intrastat_id).name else: raise exceptions.Warning( _('Product "%s" has no intrastat code, please configure it' ) % inv_line.product_id.display_name) #In extended mode, 2 more fields required if extendedmode: #Check means of transport if inv_line.invoice_id.transport_mode_id: extpc = inv_line.invoice_id.transport_mode_id.code elif company.transport_mode_id: extpc = company.transport_mode_id.code else: self._company_warning( _('The default Intrastat transport mode of your company ' 'is not set, please make sure to configure it first.' )) #Check incoterm if inv_line.invoice_id.incoterm_id: exdeltrm = inv_line.invoice_id.incoterm_id.code elif company.incoterm_id: exdeltrm = company.incoterm_id.code else: self._company_warning( _('The default Incoterm of your company is not set, ' 'please make sure to configure it first.')) else: extpc = "" exdeltrm = "" linekey = intrastatkey(EXTRF=declcode, EXCNT=excnt, EXTTA=extta, EXREG=exreg, EXGO=exgo, EXTPC=extpc, EXDELTRM=exdeltrm) #We have the key #calculate amounts if inv_line.price_unit and inv_line.quantity: amount = inv_line.price_unit * inv_line.quantity else: amount = 0 weight = (inv_line.product_id.weight or 0.0) * \ inv_line.uom_id._compute_quantity(inv_line.quantity, inv_line.product_id.uom_id) if not inv_line.product_id.uom_id.category_id: supply_units = inv_line.quantity else: supply_units = inv_line.quantity * inv_line.uom_id.factor amounts = entries.setdefault(linekey, (0, 0, 0)) amounts = (amounts[0] + amount, amounts[1] + weight, amounts[2] + supply_units) entries[linekey] = amounts numlgn = 0 for linekey in entries: amounts = entries[linekey] if round(amounts[0], 0) == 0: continue numlgn += 1 item = ET.SubElement(datas, 'Item') self._set_Dim(item, 'EXSEQCODE', text_type(numlgn)) self._set_Dim(item, 'EXTRF', text_type(linekey.EXTRF)) self._set_Dim(item, 'EXCNT', text_type(linekey.EXCNT)) self._set_Dim(item, 'EXTTA', text_type(linekey.EXTTA)) self._set_Dim(item, 'EXREG', text_type(linekey.EXREG)) self._set_Dim(item, 'EXTGO', text_type(linekey.EXGO)) if extendedmode: self._set_Dim(item, 'EXTPC', text_type(linekey.EXTPC)) self._set_Dim(item, 'EXDELTRM', text_type(linekey.EXDELTRM)) self._set_Dim(item, 'EXTXVAL', text_type(round(amounts[0], 0)).replace(".", ",")) self._set_Dim(item, 'EXWEIGHT', text_type(round(amounts[1], 0)).replace(".", ",")) self._set_Dim(item, 'EXUNITS', text_type(round(amounts[2], 0)).replace(".", ",")) if numlgn == 0: #no datas datas.set('action', 'nihil') return decl
def import_sale_pricelist(self): if self.import_option == 'csv': if (self.file): try: if self.compute_type == 'both': keys = [ 'name', 'currency', 'apply_on', 'check_apply_on', 'min_qty', 'start_dt', 'end_dt', 'compute_price', 'amount' ] else: keys = [ 'name', 'currency', 'apply_on', 'check_apply_on', 'min_qty', 'start_dt', 'end_dt', 'based_on', 'discount', 'surcharge', 'rounding', 'min_margin', 'max_margin', 'other_pricelist' ] csv_data = base64.b64decode(self.file) data_file = io.StringIO(csv_data.decode("utf-8")) data_file.seek(0) file_reader = [] csv_reader = csv.reader(data_file, delimiter=',') file_reader.extend(csv_reader) except Exception: raise exceptions.Warning(_("Invalid file!")) values = {} for i in range(len(file_reader)): field = list(map(str, file_reader[i])) values = dict(zip(keys, field)) if values: if i == 0: continue else: values.update({'option': self.import_option}) res = self.make_pricelist(values) else: raise Warning(_('Please Seelect a file.')) else: if (self.file): try: fp = tempfile.NamedTemporaryFile(delete=False, suffix=".xlsx") fp.write(binascii.a2b_base64(self.file)) fp.seek(0) values = {} workbook = xlrd.open_workbook(fp.name) sheet = workbook.sheet_by_index(0) except Exception: raise exceptions.Warning(_("Invalid file!")) for row_no in range(sheet.nrows): val = {} if row_no <= 0: fields = map(lambda row: row.value.encode('utf-8'), sheet.row(row_no)) else: line = list( map( lambda row: isinstance(row.value, bytes) and row.value.encode('utf-8') or str(row.value), sheet.row(row_no))) start_date_string = False end_dt_string = False amount = line[8] or 0 if line[5] and line[6]: start_dt = int(float(line[5])) end_dt = int(float(line[6])) start_dt_datetime = datetime(*xlrd.xldate_as_tuple( start_dt, workbook.datemode)) end_dt_datetime = datetime(*xlrd.xldate_as_tuple( end_dt, workbook.datemode)) start_date_string = start_dt_datetime.date( ).strftime('%Y-%m-%d') end_dt_string = end_dt_datetime.date().strftime( '%Y-%m-%d') min_qty = 1 if line[4]: min_qty = int(float(line[4])) if self.compute_type == 'both': values.update({ 'name': line[0], 'currency': line[1], 'apply_on': line[2].strip(), 'check_apply_on': line[3], 'min_qty': min_qty, 'start_dt': start_date_string, 'end_dt': end_dt_string, 'compute_price': line[7], 'amount': float(amount), }) res = self.make_pricelist(values) else: if not len(line) > 9: raise Warning( _("Please select proper file when you select 'Formula' option." )) return discount = line[8] or 0 surcharge = line[9] or 0 rounding = line[10] or 0 min_margin = line[11] or 0 max_margin = line[12] or 0 values.update({ 'name': line[0], 'currency': line[1], 'apply_on': line[2].strip(), 'check_apply_on': line[3], 'min_qty': min_qty, 'start_dt': start_date_string, 'end_dt': end_dt_string, 'based_on': line[7], 'discount': float(discount), 'surcharge': float(surcharge), 'rounding': float(rounding), 'min_margin': float(min_margin), 'max_margin': float(max_margin), }) if line[7].lower( ) == 'other pricelist' and line[13]: values.update({'other_pricelist': line[13]}) res = self.make_pricelist(values) else: raise Warning(_('Please Seelect a file.'))
def create_xml(self): """Creates xml that is to be exported and sent to estate for partner vat intra. :return: Value for next action. :rtype: dict """ self.ensure_one() company = self.company_id if not (company.partner_id and company.partner_id.country_id and company.partner_id.country_id.id): self._company_warning( _('The country of your company is not set, ' 'please make sure to configure it first.')) if not company.company_registry: self._company_warning( _('The registry number of your company is not set, ' 'please make sure to configure it first.')) if len(self.year) != 4: raise exceptions.Warning(_('Year must be 4 digits number (YYYY)')) #Create root declaration decl = ET.Element('DeclarationReport') decl.set('xmlns', INTRASTAT_XMLNS) #Add Administration elements admin = ET.SubElement(decl, 'Administration') fromtag = ET.SubElement(admin, 'From') fromtag.text = company.company_registry fromtag.set('declarerType', 'KBO') ET.SubElement(admin, 'To').text = "NBB" ET.SubElement(admin, 'Domain').text = "SXX" if self.arrivals == 'be-standard': decl.append(self.sudo()._get_lines(dispatchmode=False, extendedmode=False)) elif self.arrivals == 'be-extended': decl.append(self.sudo()._get_lines(dispatchmode=False, extendedmode=True)) if self.dispatches == 'be-standard': decl.append(self.sudo()._get_lines(dispatchmode=True, extendedmode=False)) elif self.dispatches == 'be-extended': decl.append(self.sudo()._get_lines(dispatchmode=True, extendedmode=True)) #Get xml string with declaration data_file = ET.tostring(decl, encoding='UTF-8', method='xml') #change state of the wizard self.write({ 'name': 'intrastat_%s%s.xml' % (self.year, self.month), 'file_save': base64.encodestring(data_file), 'state': 'download' }) return { 'name': _('Save'), 'view_type': 'form', 'view_mode': 'form', 'res_model': 'l10n_be_intrastat_xml.xml_decl', 'type': 'ir.actions.act_window', 'target': 'new', 'res_id': self.id, }
def refresh_currency(self): """Refresh the currencies rates !!for all companies now""" _logger.info( 'Starting to refresh currencies with service %s (company: %s)', self.service, self.company_id.name) rate_obj = self.env['res.currency.rate'] company = self.company_id # The multi company currency can be set or no so we handle # The two case if company.auto_currency_up: main_currency = self.company_id.currency_id if not main_currency: raise exceptions.Warning( _('There is no main ' 'currency defined!')) if main_currency.rate != 1: raise exceptions.Warning( _('Base currency rate should ' 'be 1.00!')) note = self.note or '' try: # We initalize the class that will handle the request # and return a dict of rate getter = CurrencyGetterType.get(self.service) curr_to_fetch = [x.name for x in self.currency_to_update] res, log_info = getter.get_updated_currency( curr_to_fetch, main_currency.name, self.max_delta_days) rate_name = \ fields.Datetime.to_string(datetime.utcnow().replace( hour=0, minute=0, second=0, microsecond=0)) for curr in self.currency_to_update: if curr.id == main_currency.id: continue do_create = True for rate in curr.rate_ids: if rate.name == rate_name: rate.rate = res[curr.name] do_create = False break if do_create: vals = { 'currency_id': curr.id, 'rate': res[curr.name], 'name': rate_name } rate_obj.create(vals) _logger.info('Updated currency %s via service %s', curr.name, self.service) # Show the most recent note at the top msg = '%s \n%s currency updated. %s' % ( log_info or '', fields.Datetime.to_string( datetime.today()), note) self.write({'note': msg}) except Exception as exc: error_msg = '\n%s ERROR : %s %s' % (fields.Datetime.to_string( datetime.today()), repr(exc), note) _logger.error(repr(exc)) self.write({'note': error_msg}) if self._context.get('cron', False): midnight = time(0, 0) next_run = (datetime.combine( fields.Date.from_string(self.next_run), midnight) + _intervalTypes[str(self.interval_type)]( self.interval_number)).date() self.next_run = next_run return True
def write(self, vals): if self.env.user.child_ids: raise exceptions.Warning( _('Invalid Action!\n Parent can not edit \ Subject Registration!')) return super(OpSubjectRegistration, self).write(vals)
def _check_interval_number(self): if self.interval_number < 0: raise exceptions.Warning(_('Interval number must be >= 0'))
def button_cancel(self): quant_obj = self.env['stock.quant'] model_obj = self.env['ir.model'] moves = self.env['account.move'] account_move_obj = self.env['account.move'] model = model_obj.search([('model', '=', 'stock.landed.cost')]) for order in self: if order.picking_ids and order.company_id.cancel_delivery_order_for_po : for picking in order.picking_ids: if picking.state == 'cancel': continue if model and picking.picking_type_code == 'incoming': cost_recs = self.env['stock.landed.cost'].search([('state', '=', 'done'),('picking_ids', 'in', order.picking_ids.ids)]) if cost_recs: raise exceptions.Warning('Please Remove stock landed cost "%s" related with this incoming shipment(%s) then try to cancel it.'%(','.join(cost_recs.mapped('name')),picking.name)) if picking.state not in ['done']: picking.action_cancel() else: account_moves=picking.move_lines for move in account_moves: if move.state == 'cancel': continue # move._do_unreserve() if move.state == "done" and move.product_id.type == "product": for move_line in move.move_line_ids: quantity = move_line.product_uom_id._compute_quantity(move_line.qty_done, move_line.product_id.uom_id) quant_obj._update_available_quantity(move_line.product_id, move_line.location_id, quantity) quant_obj._update_available_quantity(move_line.product_id, move_line.location_dest_id, quantity * -1) if move.procure_method == 'make_to_order' and not move.move_orig_ids: move.state = 'waiting' elif move.move_orig_ids and not all(orig.state in ('done', 'cancel') for orig in move.move_orig_ids): move.state = 'waiting' else: move.state = 'confirmed' siblings_states = (move.move_dest_ids.mapped('move_orig_ids') - move).mapped('state') if move.propagate: # only cancel the next move if all my siblings are also cancelled if all(state == 'cancel' for state in siblings_states): move.move_dest_ids._action_cancel() else: if all(state in ('done', 'cancel') for state in siblings_states): move.move_dest_ids.write({'procure_method': 'make_to_stock'}) move.move_dest_ids.write({'move_orig_ids': [(3, move.id, 0)]}) account_moves = account_move_obj.search([('stock_move_id', '=', move.id)]) if account_moves: for account_move in account_moves: account_move.button_cancel() account_move.unlink() if order.company_id.cancel_invoice_for_po: for invoice in order.invoice_ids: if invoice.journal_id and not invoice.journal_id.update_posted: invoice.journal_id.write({'update_posted':True}) if invoice.state in ['draft','open']: invoice.action_cancel() else: moves = invoice.move_id invoice.payment_move_line_ids.remove_move_reconcile() # invoice.payment_move_line_ids.button_cancel() if moves and not moves.journal_id.update_posted: moves.write({'update_posted':True}) invoice.action_cancel() res = super(PurchaseOrder,self).button_cancel() return res
def _get_intrastat_linekey(self, declcode, inv_line, dispatchmode, extendedmode): IntrastatRegion = self.env['l10n_be_intrastat.region'] company = self.company_id #Check type of transaction if inv_line.intrastat_transaction_id: extta = inv_line.intrastat_transaction_id.code else: extta = "1" #Check country if inv_line.invoice_id.intrastat_country_id: excnt = inv_line.invoice_id.intrastat_country_id.code else: excnt = inv_line.invoice_id.partner_shipping_id.country_id.code or inv_line.invoice_id.partner_id.country_id.code #Check region #If purchase, comes from purchase order, linked to a location, #which is linked to the warehouse #if sales, the sales order is linked to the warehouse #if sales, from a delivery order, linked to a location, #which is linked to the warehouse #If none found, get the company one. exreg = None if inv_line.invoice_id.type in ('in_invoice', 'in_refund'): #comes from purchase po_lines = self.env['purchase.order.line'].search( [('invoice_lines', 'in', inv_line.id)], limit=1) if po_lines: if self._is_situation_triangular(company, po_line=po_lines): return location = self.env['stock.location'].browse( po_lines.order_id._get_destination_location()) region_id = self.env[ 'stock.warehouse'].get_regionid_from_locationid(location) if region_id: exreg = IntrastatRegion.browse(region_id).code elif inv_line.invoice_id.type in ('out_invoice', 'out_refund'): #comes from sales so_lines = self.env['sale.order.line'].search( [('invoice_lines', 'in', inv_line.id)], limit=1) if so_lines: if self._is_situation_triangular(company, so_line=so_lines): return saleorder = so_lines.order_id if saleorder and saleorder.warehouse_id and saleorder.warehouse_id.region_id: exreg = IntrastatRegion.browse( saleorder.warehouse_id.region_id.id).code if not exreg: if company.region_id: exreg = company.region_id.code else: self._company_warning( _('The Intrastat Region of the selected company is not set, ' 'please make sure to configure it first.')) #Check commodity codes intrastat_id = inv_line.product_id.get_intrastat_recursively() if intrastat_id: exgo = self.env['report.intrastat.code'].browse(intrastat_id).name else: raise exceptions.Warning( _('Product "%s" has no intrastat code, please configure it') % inv_line.product_id.display_name) #In extended mode, 2 more fields required if extendedmode: #Check means of transport if inv_line.invoice_id.transport_mode_id: extpc = inv_line.invoice_id.transport_mode_id.code elif company.transport_mode_id: extpc = company.transport_mode_id.code else: self._company_warning( _('The default Intrastat transport mode of your company ' 'is not set, please make sure to configure it first.')) #Check incoterm if inv_line.invoice_id.incoterm_id: exdeltrm = inv_line.invoice_id.incoterm_id.code elif company.incoterm_id: exdeltrm = company.incoterm_id.code else: self._company_warning( _('The default Incoterm of your company is not set, ' 'please make sure to configure it first.')) else: extpc = "" exdeltrm = "" intrastatkey = namedtuple( "intrastatkey", ['EXTRF', 'EXCNT', 'EXTTA', 'EXREG', 'EXGO', 'EXTPC', 'EXDELTRM']) return intrastatkey(EXTRF=declcode, EXCNT=excnt, EXTTA=extta, EXREG=exreg, EXGO=exgo, EXTPC=extpc, EXDELTRM=exdeltrm)
def get_attendances(self): for att_sheet in self: att_sheet.att_sheet_line_ids.unlink() att_line = self.env["attendance.sheet.line"] from_date = datetime.strptime(att_sheet.date_from, "%Y-%m-%d") to_date = datetime.strptime(att_sheet.date_to, "%Y-%m-%d") emp = att_sheet.employee_id if not self.env.user.tz: raise exceptions.Warning("Please add time zone for %s" % emp.name) else: tz = pytz.timezone(self.env.user.tz) if emp.contract_id.resource_calendar_id: calender_id = emp.contract_id.resource_calendar_id else: raise ValidationError( _('Please add working hours to the %s `s contract ' % emp.name)) return if att_sheet.att_policy_id: policy_id = att_sheet.att_policy_id else: raise ValidationError( _('Please add Attendance Policy to the %s `s contract ' % emp.name)) return def _get_time_from_float(float_type): str_off_time = str(float_type) official_hour = str_off_time.split('.')[0] official_minute = ("%2d" % int( str(float("0." + str_off_time.split('.')[1]) * 60).split('.')[0])).replace(' ', '0') str_off_time = official_hour + ":" + official_minute str_off_time = datetime.strptime(str_off_time, "%H:%M").time() return str_off_time def _get_float_from_time(time): time_type = datetime.strftime(time, "%H:%M") signOnP = [int(n) for n in time_type.split(":")] signOnH = signOnP[0] + signOnP[1] / 60.0 return signOnH def interval_clean(intervals): intervals = sorted(intervals, key=itemgetter(0)) # sort on first datetime cleaned = [] working_interval = None while intervals: current_interval = intervals.pop(0) if not working_interval: # init working_interval = [ current_interval[0], current_interval[1] ] elif working_interval[1] < current_interval[ 0]: # interval is disjoint cleaned.append(tuple(working_interval)) working_interval = [ current_interval[0], current_interval[1] ] elif working_interval[1] < current_interval[ 1]: # union of greater intervals working_interval[1] = current_interval[1] if working_interval: # handle void lists cleaned.append(tuple(working_interval)) return cleaned def get_work_intervals(calender, day_start, day_end): tz_info = fields.Datetime.context_timestamp(self, day_start).tzinfo working_intervals = [] for att in calender._get_day_attendances( day_start.date(), day_start.replace(hour=0, minute=0, second=0).time(), day_end.time()): dt_f = day_start.replace( hour=0, minute=0, second=0) + timedelta(seconds=(att.hour_from * 3600)) if dt_f < day_start: dt_f = day_start dt_t = day_start.replace( hour=0, minute=0, second=0) + timedelta(seconds=(att.hour_to * 3600)) if dt_t > day_end: dt_t = day_end working_interval = (dt_f, dt_t) # print working_interval # adapt tz working_interval_tz = (dt_f.replace( tzinfo=tz_info).astimezone(pytz.UTC).replace( tzinfo=None), dt_t.replace( tzinfo=tz_info).astimezone( pytz.UTC).replace(tzinfo=None)) # print working_interval_tz working_intervals.append(working_interval_tz) clean_work_intervals = interval_clean(working_intervals) # print clean_work_intervals return clean_work_intervals # that method will clean the ovelapped leaves intervals and clean the interval from the leaves intervals @api.model def interval_without_leaves(interval, leave_intervals): if not interval: return interval if leave_intervals is None: leave_intervals = [] intervals = [] leave_intervals = interval_clean(leave_intervals) current_interval = [interval[0], interval[1]] for leave in leave_intervals: if leave[1] <= current_interval[0]: continue if leave[0] >= current_interval[1]: break if current_interval[0] < leave[0] < current_interval[1]: current_interval[1] = leave[0] intervals.append( (current_interval[0], current_interval[1])) current_interval = [leave[1], interval[1]] if current_interval[0] <= leave[1]: current_interval[0] = leave[1] if current_interval and current_interval[0] < interval[ 1]: # remove intervals moved outside base interval due to leaves intervals.append( (current_interval[0], current_interval[1])) return intervals def get_attendance_intervals(emp, calender, day_start, day_end): tz_info = fields.Datetime.context_timestamp(self, day_start).tzinfo day_st_utc = day_start.replace(tzinfo=tz_info).astimezone( pytz.utc).replace(tzinfo=None) str_day_st_utc = datetime.strftime(day_st_utc, DATETIME_FORMAT) day_end_utc = day_end.replace(tzinfo=tz_info).astimezone( pytz.utc).replace(tzinfo=None) str_day_end_utc = datetime.strftime(day_end_utc, DATETIME_FORMAT) res = [] attendances = self.env['hr.attendance'].search( [('employee_id.id', '=', emp.id), ('check_in', '>=', str_day_st_utc), ('check_in', '<', str_day_end_utc)], order="check_in") for att in attendances: check_in = datetime.strptime(att.check_in, DATETIME_FORMAT) check_out = datetime.strptime(att.check_out, DATETIME_FORMAT) res.append((check_in, check_out)) return res @api.multi def _get_emp_leave_intervals(emp, start_datetime=None, end_datetime=None): leaves = [] leave_obj = self.env['hr.holidays'] leave_ids = leave_obj.search([('employee_id', '=', emp.id), ('state', '=', 'validate'), ('type', '=', 'remove')]) for leave in leave_ids: date_from = fields.Datetime.from_string(leave.date_from) if end_datetime and date_from > end_datetime: continue date_to = fields.Datetime.from_string(leave.date_to) if start_datetime and date_to < start_datetime: continue leaves.append((date_from, date_to)) return leaves def get_public_holiday(date): public_holiday = self.env['hr.public.holiday'].search([ ('date_from', '<=', date), ('date_to', '>=', date), ('state', '=', 'active') ]) # print str(public_holiday) return public_holiday def get_overtime(policy): res = {} if policy: overtime_ids = policy.overtime_rule_ids wd_ot_id = policy.overtime_rule_ids.search( [('type', '=', 'workday'), ('id', 'in', overtime_ids.ids)], order='id', limit=1) we_ot_id = policy.overtime_rule_ids.search( [('type', '=', 'weekend'), ('id', 'in', overtime_ids.ids)], order='id', limit=1) ph_ot_id = policy.overtime_rule_ids.search( [('type', '=', 'ph'), ('id', 'in', overtime_ids.ids)], order='id', limit=1) if wd_ot_id: res['wd_rate'] = wd_ot_id.rate res['wd_after'] = wd_ot_id.active_after else: res['wd_rate'] = 1 res['wd_after'] = 0 if we_ot_id: res['we_rate'] = we_ot_id.rate res['we_after'] = we_ot_id.active_after else: res['we_rate'] = 1 res['we_after'] = 0 if ph_ot_id: res['ph_rate'] = ph_ot_id.rate res['ph_after'] = ph_ot_id.active_after else: res['ph_rate'] = 1 res['ph_after'] = 0 else: res['wd_rate'] = res['wd_rate'] = res['ph_rate'] = 1 res['wd_after'] = res['we_after'] = res['ph_after'] = 0 # print 'the overtime policy is ' + str(res) return res def get_late(policy, period): # print 'i will get late ' res = period flag = False if policy: if policy.late_rule_id: time_ids = policy.late_rule_id.line_ids.sorted( key=lambda r: r.time, reverse=True) for line in time_ids: if period >= line.time: flag = True if line.type == 'rate': res = line.rate * period elif line.type == 'fix': res = line.amount break if not flag: res = 0 return res def get_diff(policy, period): # print 'i will get diff' res = period flag = False if policy: if policy.diff_rule_id: time_ids = policy.diff_rule_id.line_ids.sorted( key=lambda r: r.time, reverse=True) for line in time_ids: if period >= line.time: flag = True if line.type == 'rate': res = line.rate * period elif line.type == 'fix': res = line.amount break if not flag: res = 0 return res def get_absence(policy, period, cnt): # print 'i will get absence' res = period # print res flag = False if policy: if policy.absence_rule_id: abs_ids = policy.absence_rule_id.line_ids.sorted( key=lambda r: r.counter, reverse=True) # print 'the absence lines is' + str(abs_ids) for ln in abs_ids: # print ln.counter if cnt >= int(ln.counter): # print "ifount amatch" res = ln.rate * period flag = True break if not flag: res = 0 return res @api.model def _get_leave(emp, date): res = {} leave_obj = self.env['hr.holidays'] leave_ids = leave_obj.search([('employee_id', '=', emp.id), ('state', '=', 'validate'), ('type', '=', 'remove')]).ids if leave_ids: for leave in leave_obj.browse(leave_ids): leave_date_from = datetime.strptime( leave.date_from, "%Y-%m-%d %H:%M:%S").date() leave_date_to = datetime.strptime( leave.date_to, "%Y-%m-%d %H:%M:%S").date() if leave_date_from <= date and leave_date_to >= date: res['leave_name'] = leave.name res['leave_type'] = leave.holiday_status_id.name return res all_dates = [(from_date + timedelta(days=x)) for x in range((to_date - from_date).days + 1)] abs_cnt = 0 for day in all_dates: day_start = day day_end = day.replace(hour=23, minute=59, second=59, microsecond=999999) data = {} day_str = day.strftime('%A') date = day.strftime('%Y-%m-%d') late_in = timedelta(hours=00, minutes=00, seconds=00) overtime = timedelta(hours=00, minutes=00, seconds=00) diff_time = timedelta(hours=00, minutes=00, seconds=00) work_intervals = get_work_intervals(calender_id, day_start, day_end) attendance_intervals = get_attendance_intervals( emp, calender_id, day_start, day_end) leaves = _get_emp_leave_intervals(emp, day_start, day_end) public_holiday = get_public_holiday(date) reserved_intervals = [] overtime_policy = get_overtime(policy_id) if work_intervals: if public_holiday: if attendance_intervals: for attendance_interval in attendance_intervals: overtime = attendance_interval[ 1] - attendance_interval[0] float_overtime = overtime.total_seconds( ) / 3600 if float_overtime <= overtime_policy[ 'ph_after']: float_overtime = 0 else: float_overtime = float_overtime * overtime_policy[ 'ph_rate'] ac_sign_in = pytz.utc.localize( attendance_interval[0]).astimezone(tz) ac_sign_out = pytz.utc.localize( attendance_interval[1]).astimezone(tz) values = { 'date': date, 'day': day_str, 'ac_sign_in': _get_float_from_time(ac_sign_in), 'ac_sign_out': _get_float_from_time(ac_sign_out), 'overtime': float_overtime, 'att_sheet_id': self.id, 'status': 'ph', 'note': "working on Public Holiday" } att_line.create(values) else: values = { 'date': date, 'day': day_str, 'att_sheet_id': self.id, 'status': 'ph', } att_line.create(values) else: for i, work_interval in enumerate(work_intervals): att_work_intervals = [] diff_intervals = [] late_in_interval = [] for j, att_interval in enumerate( attendance_intervals): if max(work_interval[0], att_interval[0]) < min( work_interval[1], att_interval[1]): current_att_interval = att_interval if i + 1 < len(work_intervals): next_work_interval = work_intervals[i + 1] if max(next_work_interval[0], current_att_interval[0]) < min( next_work_interval[1], current_att_interval[1]): split_att_interval = ( next_work_interval[0], current_att_interval[1]) current_att_interval = ( current_att_interval[0], next_work_interval[0]) attendance_intervals[ j] = current_att_interval attendance_intervals.insert( j + 1, split_att_interval) att_work_intervals.append( current_att_interval) reserved_intervals += att_work_intervals pl_sign_in = _get_float_from_time( pytz.utc.localize( work_interval[0]).astimezone(tz)) pl_sign_out = _get_float_from_time( pytz.utc.localize( work_interval[1]).astimezone(tz)) ac_sign_in = 0 ac_sign_out = 0 status = "" note = "" if att_work_intervals: if len(att_work_intervals) > 1: # print("there is more than one interval for that work interval") late_in_interval = ( work_interval[0], att_work_intervals[0][0]) overtime_interval = ( work_interval[1], att_work_intervals[-1][1]) if overtime_interval[ 1] < overtime_interval[0]: overtime = timedelta(hours=0, minutes=0, seconds=0) else: overtime = overtime_interval[ 1] - overtime_interval[0] remain_interval = ( attendance_intervals[0][1], work_interval[1]) for att_work_interval in attendance_intervals: if att_work_interval[ 1] <= remain_interval[0]: continue if att_work_interval[ 0] >= remain_interval[1]: break if remain_interval[ 0] < att_work_interval[ 0] < remain_interval[1]: diff_intervals.append( (remain_interval[0], att_work_interval[0])) remain_interval = ( att_work_interval[1], remain_interval[1]) if remain_interval and remain_interval[ 0] <= work_interval[1]: diff_intervals.append( (remain_interval[0], work_interval[1])) ac_sign_in = _get_float_from_time( pytz.utc.localize(att_work_intervals[0] [0]).astimezone(tz)) ac_sign_out = _get_float_from_time( pytz.utc.localize( att_work_intervals[-1] [1]).astimezone(tz)) else: late_in_interval = ( work_interval[0], att_work_intervals[0][0]) overtime_interval = ( work_interval[1], att_work_intervals[-1][1]) if overtime_interval[ 1] < overtime_interval[0]: overtime = timedelta(hours=0, minutes=0, seconds=0) diff_intervals.append( (overtime_interval[1], overtime_interval[0])) else: overtime = overtime_interval[ 1] - overtime_interval[0] ac_sign_in = _get_float_from_time( pytz.utc.localize(att_work_intervals[0] [0]).astimezone(tz)) ac_sign_out = _get_float_from_time( pytz.utc.localize(att_work_intervals[0] [1]).astimezone(tz)) else: late_in_interval = [] diff_intervals.append( (work_interval[0], work_interval[1])) status = "ab" if diff_intervals: for diff_in in diff_intervals: if leaves: status = "leave" # print "diff without leave clean" + str(diff_in) diff_clean_intervals = interval_without_leaves( diff_in, leaves) for diff_clean in diff_clean_intervals: diff_time += diff_clean[ 1] - diff_clean[0] else: diff_time += diff_in[1] - diff_in[0] if late_in_interval: # print "hey iam in late in " + str(late_in_interval) if late_in_interval[1] < late_in_interval[0]: late_in = timedelta(hours=0, minutes=0, seconds=0) else: if leaves: late_clean_intervals = interval_without_leaves( late_in_interval, leaves) # print"lat after clean " + str(late_clean_intervals) for late_clean in late_clean_intervals: late_in += late_clean[ 1] - late_clean[0] else: late_in = late_in_interval[ 1] - late_in_interval[0] float_overtime = overtime.total_seconds() / 3600 if float_overtime <= overtime_policy['wd_after']: float_overtime = 0 else: float_overtime = float_overtime * overtime_policy[ 'wd_rate'] float_late = late_in.total_seconds() / 3600 policy_late = get_late(policy_id, float_late) # print "policy late is " + str(policy_late) float_diff = diff_time.total_seconds() / 3600 if status == 'ab': abs_cnt += 1 # print 'absence counter=' + str(abs_cnt) float_diff = get_absence( policy_id, float_diff, abs_cnt) else: float_diff = get_diff(policy_id, float_diff) values = { 'date': date, 'day': day_str, 'pl_sign_in': pl_sign_in, 'pl_sign_out': pl_sign_out, 'ac_sign_in': ac_sign_in, 'ac_sign_out': ac_sign_out, 'late_in': policy_late, 'overtime': float_overtime, 'diff_time': float_diff, 'status': status, 'att_sheet_id': self.id } att_line.create(values) # print "resrved intervals is" + str(reserved_intervals) # print("atts work atts" + str(att_work_intervals)) out_work_intervals = [ x for x in attendance_intervals if x not in reserved_intervals ] # print "the out of work atts " + str(out_work_intervals) if out_work_intervals: for att_out in out_work_intervals: # print "out interval" + str(att_out) overtime = att_out[1] - att_out[0] ac_sign_in = _get_float_from_time( pytz.utc.localize( att_out[0]).astimezone(tz)) ac_sign_out = _get_float_from_time( pytz.utc.localize( att_out[1]).astimezone(tz)) float_overtime = overtime.total_seconds( ) / 3600 if float_overtime <= overtime_policy[ 'wd_after']: float_overtime = 0 else: float_overtime = float_overtime * overtime_policy[ 'wd_rate'] values = { 'date': date, 'day': day_str, 'pl_sign_in': 0, 'pl_sign_out': 0, 'ac_sign_in': ac_sign_in, 'ac_sign_out': ac_sign_out, 'overtime': float_overtime, 'note': "overtime out of work intervals", 'att_sheet_id': self.id } att_line.create(values) else: if attendance_intervals: # print "thats weekend be over time " for attendance_interval in attendance_intervals: overtime = attendance_interval[ 1] - attendance_interval[0] ac_sign_in = pytz.utc.localize( attendance_interval[0]).astimezone(tz) ac_sign_out = pytz.utc.localize( attendance_interval[1]).astimezone(tz) # print " the actual sign in is +" + str(ac_sign_in) float_overtime = overtime.total_seconds() / 3600 if float_overtime <= overtime_policy['we_after']: float_overtime = 0 else: float_overtime = float_overtime * overtime_policy[ 'we_rate'] values = { 'date': date, 'day': day_str, 'ac_sign_in': _get_float_from_time(ac_sign_in), 'ac_sign_out': _get_float_from_time(ac_sign_out), 'overtime': float_overtime, 'att_sheet_id': self.id, 'status': 'weekend', 'note': "working in weekend" } att_line.create(values) else: values = { 'date': date, 'day': day_str, 'att_sheet_id': self.id, 'status': 'weekend', 'note': "" } att_line.create(values)