def add_to_reseller(self): gid = read_config('groups_reseller', 3) if not Group.objects.filter(pk=gid).exists(): return False self.current.groups.add( Group.objects.get(pk=read_config('groups_reseller', 3))) return True
def create_ip_invoice(user_id, service_period=1): if not user_id: return -1 try: iph = UserIPStaticHistory() iph.user_id = user_id iph.save() srv = InvoiceService() srv.service_type = 3 srv.content_object = iph state = UserServiceStatus(user_id) if state.current_service: srv.expire_date = date_add_days_aware( state.current_service.expire_date, service_period * 30) srv.save() i = Invoice() i.user_id = user_id i.create_time = now() i.extra_data = int(service_period) tmp_price = int(read_config('service_ip_price', 10000)) * int(service_period) tax = float(read_config('invoice_tax', 0.08)) i.price = round(tmp_price + (tmp_price * float(tax)), -1) i.service = srv i.tax = tax i.service_text = _('ip static') i.save() return i.pk except Exception as e: logger.error(e.message or e.args) return -1
def __init__(self, host=None, port=None, username=None, password=None, ibs_type=1): if not validate_empty_str(host): self.hostname = read_config('ibs_address', '212.16.80.145') else: self.hostname = host if not validate_integer(port): self.port = read_config('ibs_port', '1235') else: self.port = port if not validate_empty_str(username): self.username = read_config('ibs_username', 'CRM') else: # log.debug('Setting the username') self.username = username if not validate_empty_str(password): # log.debug('Password is empty') self.password = read_config('ibs_password', '!@#CRM!@#') else: # log.debug('Setting the password') self.password = password self.proxy = xmlrpclib.ServerProxy('http://{0}:{1}/'.format(self.hostname, self.port)) self.auth_params = {"auth_name": self.username, 'auth_pass': self.password, 'auth_type': 'ADMIN'} # self.auth_params = self.__get_auth__(username, password) # print self.auth_params self.ibs_type = ibs_type
def mismatch_invoice_price(i, price, as_discount=False, default_subject_more=None, default_subject_less=None, invoice_id=None): price = int(price) diff = (i.price - i.debit_price) - price diff *= -1 if as_discount: i.dynamic_discount = diff return i if diff > 0: if default_subject_more: subject_id = default_subject_more else: subject_id = read_config('invoice_extra_payment') diff = (price - i.price) * -1 elif diff < 0: if default_subject_less: subject_id = default_subject_less else: subject_id = read_config('invoice_lower_payment') diff = i.debit_price + (diff * -1) else: subject_id = read_config('invoice_zero_payment') diff = i.debit_price if not validate_integer(subject_id): return None change_user_debit(subject_id, diff, i.user_id, _('system assign'), invoice_id) return i
def view_public_dedicated_profit(request): if request.method == 'GET': return render(request, 'public/ResellerProfit.html') elif request.method == 'POST': # base_price = 240000 action = request.POST.get('a') if action == '1': sell = get_integer(request.POST.get('s').replace(',', '')) res = { 'internet': int(sell * 1.5), 'once': int(sell), 'monthly': int(sell * 0.10) } return HttpResponse(json.dumps(res)) elif action == '2': is_special = 'cSP' in request.POST bw = get_integer(request.POST.get('b')) sell = get_integer(request.POST.get('sd').replace(',', '')) if is_special: min_price = read_config('visitor_special_min', 240000) if sell < min_price: return send_error( request, _('min price value is') + ' ' + str(min_price)) else: min_price = read_config('visitor_normal_min', 170000) if sell < min_price: return send_error( request, _('min price value is') + ' ' + str(min_price)) co_profit = (sell - min_price) * bw # B9 if is_special: one_time = co_profit * 2.2 monthly = co_profit * 0.3 else: one_time = co_profit * 2.2 monthly = co_profit * 0.3 res = {'once': int(one_time), 'monthly': int(monthly)} return HttpResponse(json.dumps(res)) elif action == '3': bw = get_integer(request.POST.get('bi')) sell = get_integer(request.POST.get('si').replace(',', '')) base_price = read_config('visitor_intranet_base_price', 30000) if sell < base_price: return send_error( request, _('min price value is') + ' ' + str(base_price)) co_profit = (sell - base_price) * bw one_time = co_profit * 2.2 monthly = co_profit * 0.3 return HttpResponse( json.dumps({ 'once': int(one_time), 'monthly': int(monthly) })) else: logger.warning('invalid action requested %s' % action) return send_error(request, _('unknown request'))
def send_text_message(user_id, text, is_password=False): if not validate_empty_str(text): return False if not validate_integer(user_id): return False text = text.encode('utf-8') username = read_config('sms_username') print username password = read_config('sms_password') line = read_config('sms_line') username_field = read_config('sms_username_field') password_field = read_config('sms_password_field') to_field = read_config('sms_target_field') text_field = read_config('sms_text_field') add_r = read_config('sms_url') line_field = read_config('sms_line_field') suc = read_config('sms_send_success') n = NotifyLog() try: # text = text.encode() user = UserProfile.objects.get(user=user_id) if not user.mobile: return False mobile = user.mobile if not add_r.lower().startswith('http://'): address = 'http://' + add_r + '?' else: address = add_r if validate_empty_str(line_field) and validate_empty_str(line): address = '{0}{1}={2}&'.format(address, line_field, line) if validate_empty_str(password_field) and validate_empty_str(password): address = '{0}{1}={2}&'.format(address, password_field, password) if validate_empty_str(username_field) and validate_empty_str(username): address = '{0}{1}={2}&'.format(address, username_field, username) if is_password: n.description = '***' else: n.description = text n.target = mobile n.notify_type = 1 n.is_read = True n.send_time = now() n.user = User.objects.get(pk=user_id) uc = urllib.urlencode({text_field: text}) address = '{0}{1}={2}&{3}'.format(address, to_field, mobile, uc) res = urlopen(address).read() res = str(res) if suc in res or suc == res: n.result = True else: n.result = False except Exception as e: print e.args[0] n.result = False finally: n.save() return n.result
def __init__(self, user, password): if not isinstance(user, str) and not isinstance(user, unicode): raise TypeError('Expected str or unicode') if not isinstance(password, str) and not isinstance(password, unicode): raise TypeError('Expected str or unicode') self.__dict__.update({'user': user, 'password': password, 'host': read_config('mail_server', 'mail.gen-co.com'), 'https': read_config('mail_https', '1')}) if self.is_secure: self.con = imaplib.IMAP4_SSL(self.__dict__.get('host')) else: self.con = imaplib.IMAP4(self.__dict__.get('host'))
def re_enable_temp(self): user = self.get_target_user(True) days = read_config('service_personnel_day', 1) amount = read_config('service_personnel_amount', 1024) d = TempChargeState.objects.filter(user=user.pk).first() if not d: d = TempChargeState() d.user_id = user.pk d.days = days d.credit = amount d.save()
def temp_charge(self, username): auth = self.auth_params user_id = self.get_user_id_by_username(username) auth['user_id'] = user_id auth['temporary_extend_credit'] = float(read_config('service_temp_amount', 700)) auth['temporary_extend_hours'] = int(read_config('service_temp_time', 2)) * 24 try: self.proxy.user.temporaryExtendUsers(auth) return True except xmlrpclib.Fault as e: print e.faultString return False
def send_gift_for_users_by_date(): marriage_users = User.objects.filter(fk_user_profile_user__marriage_date_day=datetime.today().date().day, fk_user_profile_user__marriage_date_month=datetime.today().date().month) birth_users = User.objects.filter(fk_user_profile_user__birth_date_month=datetime.today().date().month, fk_user_profile_user__birth_date_day=datetime.today().day) birth_package = read_config(name='gift_birthday_package', default=0) birth_service = read_config(name='gift_birthday_service', default=0) birth_add_limited = False marriage_package = read_config(name='gift_marriage_package', default=0) marriage_service = read_config(name='gift_marriage_service', default=0) marriage_add_limited = False # Calling Them send_gift_for_users(birth_users, int(birth_service), int(birth_package), birth_add_limited) send_gift_for_users(marriage_users, int(marriage_service), int(marriage_package), marriage_add_limited)
def get_user_name_from_ip(request): ibs = IBSManager() try: ip = get_client_ip(request) res = ibs.get_username_from_ip(ip) failed = read_config('service_failed_users') failed_ids = failed.split(',') tmp_res = None for f in failed_ids: if User.objects.filter(username=res).exists(): u = User.objects.get(username=res) if u.pk == int(f): if IBSUserInfo.objects.filter(user=f).exists(): failed_ibs_id = IBSUserInfo.objects.get(user=f).ibs_uid else: failed_ibs_id = ibs.get_user_id_by_username(res) ras_username = get_username_from_ras( ip, int(failed_ibs_id)) return ras_username else: tmp_res = res else: return None return tmp_res except Exception as e: print e.message res = None return res
def get_username_from_ras(ip_address, failed_ibs_id): try: ibs = IBSManager() online = ibs.get_user_connection_info_1(failed_ibs_id) for o in online: try: if o[4] == ip_address: ras = o[0] util = MKUtils(ras, read_config('ras_username', 'saeed'), read_config('ras_password', 'saeed')) return util.get_user_by_ip(ip_address) except Exception as e: print e.message continue except Exception as e: print e.message
def config_management(request): if request.method == 'GET': reload_from_cache = request.GET.get('relocate', '0') == 'YES!PLEASE!' conf = get_config() data = {} sections = conf.sections() for s in sections: opt = {} ox = conf.options(s) for o in ox: if reload_from_cache: new_config = read_config('%s_%s' % (s, o)) set_config(s, o, new_config) dx = {o: new_config} else: dx = {o: conf.get(s, o)} opt.update(dx) data.update({s: opt}) return render(request, 'configuration/ConfigManagement.html', {'data': data}) elif request.method == 'POST': name = get_string(request.POST.get('name')) value = get_string(request.POST.get('value')) if not name: return send_error(request, _('invalid item')) if not value: return send_error(request, _('invalid value')) section = name.split('__') if len(section) < 2: return send_error(request, _('invalid value')) set_config(section[0], section[1], value) load_config(True) return HttpResponse('200') else: return send_error(request, _('invalid method'))
def pay(self): invoice = Invoice.objects.get(pk=self.invoice_id) if invoice.is_paid: return self if self.comment: invoice.comment = self.comment invoice.is_paid = True if self.online_payment: invoice.paid_online = True change_user_debit(read_config('invoice_zero_payment'), invoice.debit_price, invoice.user_id, _('system assign')) else: invoice.paid_online = False invoice.is_personnel_payment = self._is_personnel invoice.is_system_payment = self._is_system if self.price != invoice.price: invoice = mismatch_invoice_price(invoice, self.price, self.include_discount, self.default_subject_more, self.default_subject_less, invoice.pk) invoice.ref_number = self.bank_ref_code invoice.pay_time = now() self._invoice = invoice service_update_request.send_robust('PayInvoice', invoice=self._invoice, request=self.request) return self
def add_partner_to_job(request): dash = validate_dashboard(request.POST.get('d'), request.user) tu = validate_user(request.POST.get('t')) cmd = get_integer(request.POST.get('c')) max_users = int(read_config('dashboard_max_partner', 5)) if not dash: return send_error(request, _('invalid dashboard')) if not tu: return send_error(request, _('invalid user')) if not cmd: return send_error(request, _('invalid item')) if cmd == 1: if TicketTeam.objects.filter(dashboard=dash.pk, user=tu.pk).exists(): return send_error(request, _('this user has been selected before')) if TicketTeam.objects.filter(dashboard=dash.pk).count() >= max_users: return send_error(request, _('max users selected')) tt = TicketTeam() tt.user = tu tt.dashboard = dash tt.save() msg = '%s : %s' % (_('user added to job'), tu.first_name) add_work_history_outbox(dash, request.user, msg) elif cmd == 2: if not TicketTeam.objects.filter(dashboard=dash.pk, user=tu.pk).exists(): return HttpResponse('200') TicketTeam.objects.get(dashboard=dash.pk, user=tu.pk).delete() msg = '%s : %s' % (_('user removed from job'), tu.first_name) add_work_history_outbox(dash, request.user, msg) return HttpResponse('200')
def create_internet_account(request): if request.method == 'GET': uid = request.GET.get('u') if not validate_integer(uid): return send_error(request, _('no user selected')) if not User.objects.filter(pk=uid).exists(): return redirect('/') ibs = IBSManager() rnd = ''.join(random.choice(string.lowercase) for i in range(5)) u = User.objects.get(pk=uid) u.is_active = True if not ibs.add_new_user(u.username, rnd, 0): return send_error(request, _('unable to create ibs user')) u.set_password(rnd) u.save() ib_id = ibs.get_user_id_by_username(u.username) ibi = IBSUserInfo() ibi.ibs_uid = int(ib_id) ibi.user = u ibi.save() u.groups.add(Group.objects.get(pk=int(read_config('groups_customer', 1)))) update_ibs_user_from_crm(u.pk) fire_event(4537, u, None, request.user.pk) return redirect('/user/nav/?uid=%s' % uid) else: return redirect('/')
def update(self, force_add=False): name = self.get_str('n', True) email = self.get_str('e', True) mobile = self.get_str('m', True, max_len=12) tel = self.get_str('t', True, max_len=15) password = self.get_str('p', True) retype = self.get_str('rp', True) gender = self.get_bool('gn') if password != retype: self.error(_('passwords are not match'), True) if User.objects.filter(email=email).exists(): self.error(_('email is exists'), True, 'e') u = User() u.email = email u.username = email u.is_staff = True u.set_password(password) u.first_name = name u.save() up = UserProfile() up.address = '-' up.identity_number = '-' up.is_visitor = True up.mobile = mobile up.telephone = tel up.user = u up.gender = gender up.save() u.groups.add(read_config('groups_visitor', 14)) vp = VisitorProfile() vp.user_id = u.pk vp.deposit = 0 vp.payment_type = 0 vp.save()
def kill_user(user_id, ip_address): if not validate_integer(user_id): return False try: ibs = IBSManager() if IBSUserInfo.objects.filter(user=user_id).exists(): ibs_uid = IBSUserInfo.objects.get(user=user_id).ibs_uid else: ibs_uid = ibs.get_user_id_by_username( User.objects.get(pk=user_id).username) if ibs.kill_user(ibs_uid): return True failed_user_id = read_config('service_failed_users', 3306) failed_user_ids = failed_user_id.split(',') for f in failed_user_ids: if IBSUserInfo.objects.filter(user=f).exists(): f_ibi = IBSUserInfo.objects.get(user=f).ibs_uid elif ip_address is not None: fu = User.objects.get(pk=f) f_ibi = ibs.get_user_id_by_username(fu.username, True) else: return False connections = ibs.get_user_connection_info_1(f_ibi) for c in connections: if c[4] == ip_address: ibs = IBSManager() if ibs.kill_failed_user(c[2], f_ibi, c[0]): return True return False except Exception as e: print e.message return False
def calculate_service_price(self, items_price): service_price = items_price # 19200 original_tax = int(service_price * float(read_config('invoice_tax', 0.09))) # 1728 rounded_tax = int(math.ceil(original_tax / 100) * 100) # 1700 round_down_tax = original_tax - rounded_tax # 28 service_final_price = service_price + original_tax res = self.calc_debit(service_final_price) price_original = res[1] # 20428 rounded_original_price = int( math.ceil(int(price_original) / 100) * 100) remain_price = price_original - rounded_original_price if rounded_original_price < 100: self.error(_('system error'), True) logger.error('invalid price to calculate for user') res = { 'input_price': items_price, 'input_price_tax': original_tax, 'rounded_tax': rounded_tax, 'round_tax_amount': round_down_tax, 'debit_price': res[0], 'price_to_pay': rounded_original_price, 'remain_100_price': remain_price, 'main_price': price_original } return res
def get_max_charges(uid): """ Get the max allowed changes for user @param uid: user id @type uid: str @return: (credit, days) @rtype: (int, int) """ state = UserServiceStatus(uid) data = TempChargeState.objects.filter( user=uid).first() # only 1 Hit to DB! cs = state.current_service is_float_mode = read_config('service_temp_float', '0') == '1' if cs: x = Utils.get_service_price(cs) if data: credit = data.credit if state.is_unlimited: credit = 0 days = data.days if not is_float_mode: temp_days = int(read_config('service_temp_time', 2)) temp_amount = int(read_config('service_temp_amount', 1024)) if days > temp_days: days = temp_days # TempChargeManagement.update_state(uid, 0, days, True, True) if credit > temp_amount: # TempChargeManagement.update_state(uid, credit, 0, True, True) credit = temp_amount else: if state.is_limited: credit = int(read_config('service_temp_amount', 1024)) else: credit = 0 days = int(read_config('service_temp_time', 2)) TempChargeManagement.update_state(uid, credit, days, True, True) if not state.account_expired: days = 0 if state.credit > 100: credit = 0 if data.total_count > 3: return 0, 0, 0, 0 return credit, days, x.day, x.package else: return 0, 0, 0, 0
def calculate_temp_rate(user_id): user = User.objects.filter(pk=user_id).first() if not user: return 0 years = get_distant_from_today(user.date_joined) base_rate = read_config('service_base_extra_temp', 25) rate = years * base_rate return rate
def __calculate_for_price_pack__(self): tax = float(read_config(name='invoice_tax', default=0.09)) tax = self.service.amount * tax self.final_price = self.service.amount + tax self.extra_data['tax'] = tax self.is_success = True self.error = None self.error_cod = 0
def pay_invoice(request): if request.method == 'GET': fid = request.GET.get('f') if not validate_integer(fid): return redirect(reverse(show_all_invoices)) try: f = Invoice.objects.get(pk=fid) if f.is_paid: fire_event(4163, f, None, None) # send_to_dashboard(4163, f.user_id, None) return redirect(reverse(show_all_invoices)) data = BankProperties.objects.filter( bank__internal_value=identifier) terminal_id = long(data.get(name=properties[2]).value) bank_username = data.get(name=properties[0]).value bank_password = data.get(name=properties[1]).value bml = BMLPaymentAPI(bank_username, bank_password, terminal_id) # order_id = long(f.pk) price = long(f.price - f.debit_price) * 10 # rial correction call_back = str( read_config(name='login_base_address') + 'factor/mrt/') error_counter = 0 f.comment = _('bank mellat payment') f.save() while error_counter < 10: t = InvoicePaymentTracking() t.invoice = f t.start_time = datetime.today() t.end_time = datetime.now() t.save() res = bml.request_pay_ref(long(t.pk), price, call_back, '') if res: t.initial_res = res t.save() # send_to_dashboard(5727, f.user_id) fire_event(5727, t, None, None) # l.info("Got the token from bank : %s" % res) return render( request, 'finance/payment/mellat/Payment.html', { 'invoice': f, 'rid': res, 'action_page': bml.get_payment_address() }) else: error_counter += 1 t.is_success = False t.end_time = datetime.today() t.final_res = 'INIT ERROR' continue # send_to_dashboard(5505, f.user_id) fire_event(5505, f, None, None) return redirect(reverse(show_all_invoices)) except Exception as e: em = " ".join(e.args) print("Unable to complete payment request : %s" % em) return render(request, 'errors/ServerError.html') else: return render(request, 'errors/AccessDenied.html')
def send_email(text, to_address, title, user_id, is_password=False): try: n = NotifyLog() n.send_time = now() n.target = to_address if is_password: n.description = "***" else: n.description = text n.notify_type = 2 n.is_read = True n.user = User.objects.get(pk=user_id) # n.users_user = User.objects.get(email=to_address) if to_address is None: n.result = False n.save() return False to_email = to_address servername = read_config('mail_address') username = read_config('mail_username') password = read_config('mail_password') msg = MIMEMultipart('alternative') msg.set_unixfrom('author') msg['To'] = email.utils.formataddr(('Recipient', to_email)) msg['From'] = email.utils.formataddr((title, read_config('mail_username'))) msg['Subject'] = 'CRM' server = smtplib.SMTP(servername, 587) except Exception as e: print e.message return False try: server.set_debuglevel(True) server.ehlo() if server.has_extn('STARTTLS'): server.starttls() server.ehlo() server.login(str(username), str(password)) server.sendmail(read_config('mail_username'), [to_email], msg.as_string()) n.result = True n.save() except Exception as e: print e.args[1] finally: server.quit()
def remove_calendar_event(dash): if read_config('dashboard_remove_early', '0') == '1': if dash.fk_calendar_dashboard.exists(): cal = dash.fk_calendar_dashboard.get() today_sh = JalaliDatetime.today() if cal.cal_day > today_sh.day and cal.cal_month >= today_sh.month and cal.cal_year >= today_sh.year: cal.delete() elif cal.cal_day == today_sh.day and cal.cal_month == today_sh.month and cal.cal_year == today_sh.year: if cal.work_time.start_time >= today_sh.time(): cal.delete()
def is_near_expire_date(d, near_time=3): if not isinstance(d, datetime.datetime): return True if is_aware(d): d = make_naive(d) unlock_day = (datetime.datetime.today() + timedelta(int(read_config('service_unlock_recharge', 2)))) if d <= unlock_day: return True else: return False
def add_new_user(self, username, password, credit): if not validate_empty_str(username): return False if not validate_empty_str(password): return False try: auth = self.auth_params auth['owner_name'] = read_config('ibs_username', 'CRM') auth['group_name'] = 'no_group' auth['credit_comment'] = 'test' auth['count'] = 1 auth['credit'] = credit auth['isp_name'] = read_config('ibs_isp', 'Main') uid = self.proxy.user.addNewUsers(auth) # log.info('User has been created via : {0}'.format(uid)) self.assign_username(username, password, str(uid[0])) return True except xmlrpclib.Fault as e: print e.faultString return False
def get_next_4_days(event_id, only_times_pk=False): init_days = int(read_config('calendar_show_days', 5)) today = JalaliDatetime.today() res = [] days_collected = False # for i in range(0, init_days + 1): i = 0 while not days_collected: now = today + timedelta(days=i) while get_holidays(now.month, now.day): i += 1 now = today + timedelta(days=i) qs = Calendar.objects.filter(cal_month=now.month, cal_year=now.year, cal_day=now.day, work_time__event_type=event_id) nw = get_match_day(now.weekday()) if qs.exists(): rsc = WorkingTime.objects.filter( week_day=nw, is_deleted=False, event_type=event_id).filter( fk_calendar_working_time__cal_day=now.day, fk_calendar_working_time__cal_month=now.month, fk_calendar_working_time__cal_year=now.year).annotate( rx=Count('fk_calendar_working_time__work_time') ).filter(resource__lte=F('rx')).values_list('pk', flat=True) times = WorkingTime.objects.filter( week_day=nw, event_type=event_id).exclude(pk__in=rsc) if now.day == today.day: times = times.filter(start_time__gte=datetime.today().time()) # for r in rsc: # print r.name,";", r.rx # times = rsc else: if now.day == today.day: times = WorkingTime.objects.filter( week_day=nw, is_deleted=False, event_type=event_id, start_time__gte=datetime.today().time()) else: times = WorkingTime.objects.filter(week_day=nw, is_deleted=False, event_type=event_id) if only_times_pk: res.append(times.values_list('pk', flat=True)) else: times = times.values('pk', 'name', 'start_time', 'end_time', 'resource') res.append(FreeTimes(list(times), now.strftime('%Y-%m-%d %A'))) i += 1 if len(res) >= init_days: days_collected = True return res
def generate_username(): try: pat = read_config('login_pattern', '%Y') jd = JalaliDatetime.today() pat = jd.strftime(pat) rand = random.randint(100, 999) pat = pat.replace("RAND", str(rand)) return pat except Exception as e: print e.message return ''
def gen_invoice(uid, credit, days, lock_mode=False): """ Generate Invoice @param lock_mode: bool @param uid: user id @type uid: str|int @param credit: credit used to charge @type credit: int @param days: charged days @type days: int @return: Invoice id @rtype: int """ current_service = UserCurrentService.objects.get(user=uid) prices = Utils.get_service_price(current_service) package_price = prices.meg service_price = days * prices.day ti = TempInvoice() ti.credit = credit ti.credit_price = credit * package_price ti.days = days ti.days_price = service_price ti.user_id = uid ti.save() i = Invoice() ic = InvoiceService() ic.content_object = ti ic.service_type = 6 exp_date = date_add_days_aware(current_service.expire_date, days) ic.expire_date = exp_date ic.save() i.user_id = uid i.comment = _('temp charge') i.create_time = now() if lock_mode: user_debit = UserDebit.objects.filter(user=uid).first() if user_debit: i.debit_price = user_debit.amount else: i.debit_price = 0 else: i.debit_price = 0 i.dynamic_discount = 0 i.extra_data = 0 # i.price = (ti.days_price + ti.credit_price) i.tax = (ti.days_price + ti.credit_price) * float( read_config('invoice_tax', 0.09)) i.price = (ti.days_price + ti.credit_price) + i.tax i.service_text = _('temp charge invoice') i.service = ic i.save() return i.pk