Пример #1
0
    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()
Пример #2
0
 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
Пример #3
0
 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)
Пример #4
0
    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
Пример #5
0
    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'])
Пример #6
0
    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('.')
Пример #7
0
    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))