def _read_(self): """ Чтение тарифов МТС в : names, codes, tariff, tariff2, tarspsmg, taraspsmg """ db = MySQLdb.Connect(**self.dsn) cur = db.cursor() # направления: names['797'] = dict(name='Нижегородская', zona=2, type='MG', tara=0.81, code1='831') # список тел. кодов с привязкой к направлению: codes['code_nid_stat'], напр. codes['7831_797_MN'] sql = "select `nid`, `type`, `name`, `zona`, `code1`, `code2`, `tar` from {table} where `type`<>'VZ'".\ format(table=self.tabcode) cur.execute(sql) for line in cur: nid, _type, name, zona, code1, code2, tar = line self.names[str(nid)] = dict(name=name.encode('utf8'), zona=zona, type=_type, tara=tar, code1=code1) arrcode = Func.arraycode(code1, code2) for x in arrcode: self.codes.append(self.join_codenidstat( x, nid, _type)) # code_nid_stat self.codes.sort() # (пока) клиентский тариф с привязкой кода клиента к направлению: tariff['nid_cid'] = стоит_1_мин # клиентский тариф с привязкой кода тарифного плана к направлению : tariff2['nid_tid'] = стоит_1_мин sql = "select `tid`, `nid`, `cid`, `tar` from {table}".format( table=self.tabtarmts) cur.execute(sql) for line in cur: tid, nid, cid, tar = line self.tariff[self.join_nidcid(nid, cid)] = tar self.tariff2[self.join_nidtid(nid, tid)] = tar # агентский тариф СПС МГ с привязкой к зоне: taraspsmg['zona']=dict(tara=1.1, name='Россия (моб) 4 зона') sql = "select `name`, `zona`, `tar` tara from `{tabcode}` WHERE `regkom` like 'Rossia_mob-%'".format( tabcode=self.tabcode) cur.execute(sql) for line in cur: name, zona, tara = line self.taraspsmg[str(zona)] = dict(tara=tara, name=name) # (mtsTar) клиент_тариф СПС МГ+ВЗ с привязкой к зоне: tarspsmg['zona_cid'] (ex. tarspsmg['6_273']=7.5) sql = "select t.`cid`, t.`tid`, k.`name`, k.`zona`, k.`tar` tara, t.`tar` from `{tabcode}` k JOIN `{tabtar}`" \ " t ON k.`nid`=t.`nid` WHERE k.`regkom` like 'Rossia_mob-%' or k.`type` = 'VZ'".\ format(tabcode=self.tabcode, tabtar=self.tabtarmts) cur.execute(sql) for line in cur: cid, tid, name, zona, tara, tar = line if zona == -1: # zona=-1 СПС в komstarCode == zona=0 СПС в defCode zona = 0 self.tarspsmg[self.join_zonacid(zona, cid)] = tar self.tarspsmg2[self.join_zonatid(zona, tid)] = tar cur.close() db.close()
def is_vpn(self, num): """ возвращает True/False - номер ВПН или нет """ n = Func.get_number_7digits(num) #if n in self.numbers_vpn: # return True #else: # return False return n in self.numbers_vpn
def get_vpn_cidorg(self, num): """ Проверка номера на ВПН и если номер ВПН, то : возвращает кортеж (cid,org) (код клиента и принадлежность к организации) :param num: номер: 8495626xxxx or 626xxxx ... :return: кортеж (cid,org) или (0,'-') если не номер не ВПН """ num = Func.get_number_7digits(num) cidorg = self.numbers_vpn.get(num, "0;-") return Numbers.split_cidorg(cidorg)
def _get_cidorg(self, num): """ По номеру возвращает строку "cid;org" (код клиента и принадлежность к организации) :param num: номер: 8495626xxxx or 626xxxx or 811xxxx or 710xxxx, ... :return: строку 'cid;org' или 0 """ num = Func.get_number_7digits(num) # сначала ищем в telefon.tel, а затем в таблице tarif.vmCode cidorg = self.numbers.get(num, None) if not cidorg: cidorg = self.n811.get_cidorg(num) return cidorg
def __init__(self, dsn, table, n811): """ Все городские номера (xxxxxxx) из telefon.tel :param dsn: dsn - инфо подключения к telefon.tel :param table: период, ex. Y2016M02 - нужен для инфо по номерам из истории за период :param n811: instance Number811 """ self.n811 = n811 db = MySQLdb.Connect(**dsn) cur = db.cursor() # текущие номера: (поле fSplit - маркирует номера ВПН : + or -) sql = "select `number`, `cid`, `fOrg` `org`, `fSplit` `vpn` FROM `telefon`.`tel` where `number` like '_______'" cur.execute(sql) for line in cur: num, cid, org, vpn = line n = num[:7] if self.numbers.get(n, 0) == 0: self.numbers[n] = Numbers.join_cidorg(cid, org) # 'cid;org' if vpn == '+': self.numbers_vpn[n] = Numbers.join_cidorg(cid, org) # 'cid;org' # номера из истории за расчётный месяц dt = Func.date_first_day_month(table) sql = "select `number`, `cid`, `org` from `telefon`.`history` where `number` like '_______' and d2>='{dt}'".\ format(dt=dt) cur.execute(sql) for line in cur: num, cid, org = line n = num[:7] if self.numbers.get(n, 0) == 0: self.numbers[n] = Numbers.join_cidorg(cid, org) # 'cid;org' cur.close() db.close() # добавочные номера for n in self.numadd: if self.numbers.get(n, -1) == -1: self.numbers[n] = "0;-" # '0;-' # дополнительно for aon, v in list(self.aon_replace.items()): if self.numbers.get(aon, -1) == -1: self.numbers[aon] = Numbers.join_cidorg( int(v['cid']), v['org'])
def bill(self, dsn, info, where=None, save_db=True): """ Главная ф-ия биллинга :param dsn: параметры подключения к базе :param info: текст для логирования :param where: доп_условия отбора записей :param save_db: True|False: True-сохранять изменения в базе; False-вывод на экран """ t1 = time.time() db = MySQLdb.Connect(**dsn) cursor = db.cursor() table = self.opts.table # для результатов res = result.Result() # объект для обновления записи upd = Update(dsn=dsn, table=table) # календарь cal = calendar.Calendar(dsn=cfg.dsn_cal, table=table) # бизнес правила (могут менять плательщика и в результате сумму) # rul = rules.Rules(dsn=cfg.dsn_tel, table='rule_bill') # инфо по одной связи q = link.Link() q.prn_title() sql = "select id, dt, fm, fmx, `to`, tox, sec, min, op from `{table}` where sec>0".format(table=table) if where: sql = "{sql} and {where}".format(sql=sql, where=where) cursor.execute(sql) bar = Progressbar(info=info, maximum=cursor.rowcount) count_noexist_number = 0 step, step_update, sum_cust = (0, 0, 0.,) for line in cursor: step += 1 if save_db: bar.update_progress(step) q.__init__() q.id, q.dt, q.fm, q.fmx, q.to, q.tox, q.sec, q.min, q.op = line q.dnw = cal.dnw(q.dt) q.to2 = q.to q.to = Func.prepare_to(q.to) q.fm2 = Func.get_number_fm2(q.fm, q.fmx) # print "{dt} {fm} {to} {tox} {sec} {min}".format(dt=q.dt, fm=q.fm, to=q.to, tox=q.tox, sec=q.sec,min=q.min) # по номеру узнаем клиента q.cid, q.org, q.vpn = self.numbers.get_cidorg(q.fm, q.fmx) # у клиента может быть замена q.cid = self.cust_replace.get_cid_new(q.cid) # если за номер некому платить, запомним номер и продолжим if q.cid == '0': Func.save_noexist_number(db=dsn['db'], table=table, idx=q.id, fm=q.fm, fmx=q.fmx, to=q.to, stat=self.ctype.getsts(q.to, q.tox), filename=self.opts.filenoexistnumber) count_noexist_number += 1 continue # инфо по клиенту cst = self.cust.get_cust(q.cid) q.uf, q.cust, q.tid_t = (cst.uf, cst.custalias, cst.tid_t) q.pid = 0 if q.uf == 'f': q.pid = self.custks.get_pid_by_number(q.fm) q.tid_t = self.custks.get_cust(q.pid).tid # стоимость 1 мин и тд. # 2020-12-24 number -> cid -> tid -> cost 1 min q.sts, q.code, q.zona, q.tar, q.tara, q.nid, q.desc, q.name = \ self.mts.get_sts_code_zona_tar_tara_nid_desc_name(tid=q.tid_t, org=q.org, to=q.to, tox=q.tox) q.stat = self.ctype.get_mwszg(q.sts) # M, W, S, Z, G, V q.st = cfg.stat2st.get(q.stat, '-') # MG VZ GD # в итоге - стоимость разговора q.sum = q.tar * q.min # sum - сумма клиенту (ЮЛ-без НДС; ФЛ-с НДС) q.suma = q.tara * q.min # suma - агенту (без НДС) q.sum2 = q.sum # sum2 - сумма клиенту без НДС # для физлиц НДС включён в тариф if q.uf == 'f': q.sum2 = calc.sum_without_nds(q.sum) # sum2 для ФЛ - вычитаем НДС q.pid = self.custks.get_pid_by_number(q.fm) # бизнес-правила: if q.sec <= int(cfg.calc['minsec']): q.sum = q.sum2 = q.suma = q.sec = q.min = 0 # общая сумма без НДС sum_cust += float(q.sum2) # результат if q.sum > 0: res.add(q.sts, q.sec, q.min, q.sum2, q.suma) # обновление записи if save_db: upd.update(lnk=q) step_update += 1 else: q.prn() if count_noexist_number: print(("!номеров, отсутствующих в базе:{count}".format(count=count_noexist_number))) t2 = time.time() itog_log(info=res.result_all()) itog_log(info, step=step, update=step_update, tm1=t1, tm2=t2, cost=sum_cust, min_mg=res.get_result_mg()['min']) # обновление полей таблицы records = upd.update_table() itog_log(info="updated: {records} records: field = _field ".format(records=records)) itog_log('.')
def write_codevz_file(self, filename=None, filename2=None): """ Сохранение кодов ВЗ-связи в файле в компактном виде (для вставки в komstarCode: для строки regkom='Moskow_mob' в поле code2 ) :param filename: имя файла для сохранения кодов ВЗ-связи :param filename2: имя файла для сохранения кодов ВЗ-связи для Инител: (id;code;oper;ts) """ """ если возможно, то сжиматся для компактности: - 9005550000-9005555549 -> 9005550000-9005555549 (нечего сокращать) - 9011800000-9011899999 -> 901180-901189 (4 нуля и 4 девятки) - 9014700000-9014709999 -> 901470-901470 -> 901470 - 9411000000-9411004999 -> 9411000-9411004 (3 нуля и 3 девятки) """ vz_debug = list() vz = list() vz2 = list() opers = dict() # opers[name]=alias # список операторов с полным и кратким названием sql = "select `name`, `alias` from opers" self.cur.execute(sql) for line in self.cur: name, alias = line opers[name] = alias # коды ВЗ связи sql = "select `abc`, `fm`, `to`, `oper` from `{table}` where `stat`='vz'".format(table=self.tabCode) self.cur.execute(sql) for line in self.cur: # 900 5550000 5555549 5550 : 9005550000 - 9005555549 # 900 5555551 5559999 4449 : 9005555551 - 9005559999 # 900 6110000 6199999 90000 : 9006110000 - 9006199999 -> 900611-900619 # 901 4610000 4619999 10000 : 9014610000 - 9014619999 -> 901461-901461 -> 901461 abc, fm, to, oper = line start = "{abc}{x}".format(abc=abc, x=Func.strz(fm, 7)) end = "{abc}{x}".format(abc=abc, x=Func.strz(to, 7)) a = x = "{start}-{end}".format(start=start, end=end) if start.endswith('0000') and end.endswith('9999'): start = start[:-4] end = end[:-4] a = "{start}-{end}".format(start=start, end=end) x = "{x} : {a}".format(x=x, a=a) elif start.endswith('000') and end.endswith('999'): start = start[:-3] end = end[:-3] a = "{start}-{end}".format(start=start, end=end) x = "{x} : {a}".format(x=x, a=a) if start == end: a = "{start}".format(start=start) x = "{x} : {a}".format(x=x, a=a) vz_debug.append(x) vz.append(a) vz2.append("{a}:{oper_alias}".format(a=a, oper_alias=opers.get(oper, '.'))) step = 0 vz_debug.sort() for x in vz_debug: xprint("{x}".format(x=x)) step += 1 xprint("itogo:{itogo} records".format(itogo=step)) xprint("--------------------") vz.sort() for x in vz: xprint("{x}".format(x=x)) step += 1 xprint("itogo:{itogo} records".format(itogo=step)) # в строчку st = ','.join(vz) xprint(st) f = open(filename, "w", encoding='utf8') f.write(st) f.close() # в столбик f = open(filename+"2", "w", encoding='utf8') for x in vz: f.write("{x}\n".format(x=x)) step += 1 # exit(1) # 2016-07-31 # плоский список кодов ВЗ-связи для биллинга Инител # id; code; oper; ts xprint("/////////////////////////////////") f = open(filename2, "w", encoding='utf8') f.write("{id};{code};{oper};{stat};{ts}\n".format(id='id', code='code', oper='oper', stat='stat', ts='ts')) step1 = 0 step2 = 0 now = datetime.datetime.now() ts = "{year:04d}{month:02d}{day:02d}{hh:02d}{mm:02d}{ss:02d}".format( year=now.year, month=now.month, day=now.day, hh=now.hour, mm=now.minute, ss=now.second) stat = 'Z' # Z=Внутризоновая for xoper in vz2: x, oper = xoper.split(':') xprint("{x} {oper}".format(x=x, oper=oper)) step1 += 1 if x.find('-') > -1: start, end = x.split('-') start = int(start) end = int(end) for n in range(start, end+1): xprint("\t{n} {oper}".format(n=n, oper=oper)) f.write("{id};{code};{oper};{stat};{ts}\n".format(id=0, code=n, oper=oper, stat=stat, ts=ts)) step2 += 1 else: xprint("\t{x} {oper}".format(x=x, oper=oper)) f.write("{id};{code};{oper};{stat};{ts}\n".format(id=0, code=x, oper=oper, stat=stat, ts=ts)) step2 += 1 f.close() xprint("vz-compress/vz-plain:{step1}/{step2} records".format(step1=step1, step2=step2))