Commit 802e1d6c by Javier

Soluciones Errores

parent c651b8d1
from typing import Tuple
from winreg import QueryInfoKey
import mariadb import mariadb
from requests import get
DB_CREDENTIALS = { DB_CREDENTIALS = {
'host': '192.168.2.220', 'host': '192.168.2.220',
...@@ -9,16 +12,61 @@ DB_CREDENTIALS = { ...@@ -9,16 +12,61 @@ DB_CREDENTIALS = {
} }
def account_data(callerid: str) -> dict: def get_dids_account(username: str) -> Tuple:
"""Obtiene todos los DID asociados a una Cuenta
Args:
username (str): Nombre de Usuario
Returns:
Tuple: DID Asoaciados y el Destino
"""
with mariadb.connect(**DB_CREDENTIALS) as cnx: with mariadb.connect(**DB_CREDENTIALS) as cnx:
with cnx.cursor() as cursor: with cnx.cursor() as cursor:
headers = ['account', 'secret', 'credit'] headers = ['did', 'dest']
cursor.execute( cursor.execute(
'SELECT car.username, car.uipass, round(car.credit, 2) credit FROM cc_callerid cid\ 'SELECT did.did, dest.destination FROM cc_did did \
INNER JOIN cc_card car ON car.id=cid.id_cc_card WHERE cid.cid=?', LEFT JOIN cc_card card ON did.iduser=card.id \
(callerid,) LEFT JOIN cc_did_destination dest ON did.id=dest.id_cc_did \
WHERE card.username=?', (username,)
) )
data = cursor.fetchall()
return tuple(data)
def account_data(callerid: str = None, account : str = None) -> dict:
"""Consulta los datos de una Cuenta A2Billing
Args:
callerid (str): Número de Teléfono.
Returns:
dict: Datos de la Cuenta
"""
with mariadb.connect(**DB_CREDENTIALS) as cnx:
with cnx.cursor() as cursor:
headers = ['account', 'secret', 'credit', 'dids']
query = 'SELECT car.username, car.uipass, round(car.credit, 2) credit\
FROM cc_callerid cid\
INNER JOIN cc_card car ON car.id=cid.id_cc_card\
INNER JOIN cc_did did ON did.iduser=car.id\
INNER JOIN cc_did_destination des ON des.id_cc_did=did.id'
if account and callerid:
query += f' WHERE car.username=\'{account}\' OR cid.cid=\'{callerid}\''
elif account:
query += f' WHERE car.username = \'{account}\''
else:
query += f' WHERE cid.cid = \'{callerid}\''
cursor.execute(query)
data = cursor.fetchone() data = cursor.fetchone()
return dict(zip(headers, data)) if data else None return dict(zip(headers, data + get_dids_account(data[0]))) if data else None
if __name__ == '__main__':
print(account_data('956368558'))
...@@ -47,12 +47,19 @@ def update_sip_accounts() -> 'Tuple[int,int]': ...@@ -47,12 +47,19 @@ def update_sip_accounts() -> 'Tuple[int,int]':
with cnx.cursor() as cursor: with cnx.cursor() as cursor:
with typer.progressbar(get_accounts(only_fullyported=True), label="Sincronizando Cuentas") as accounts: with typer.progressbar(get_accounts(only_fullyported=True), label="Sincronizando Cuentas") as accounts:
for account in accounts: for account in accounts:
# Tarifa Plana
flat_rate = account.plan == 4
# Saldo, 999 si es Tarifa Plana
credit = 999.99 if flat_rate else account.credit
cursor.execute( cursor.execute(
"UPDATE [bdd_wifi].[dbo].[TB_ServicioFijo]\ "UPDATE [bdd_wifi].[dbo].[TB_ServicioFijo]\
SET SaldoActual=?, Activo=?, TarifaPlana=?, Pospago=?, IdTarifa=?,\ SET SaldoActual=?, Activo=?, TarifaPlana=?, Pospago=?, IdTarifa=?,\
UsuarioEXT=?, ClaveEXT=?, NuevaPlataforma=1 WHERE DDI=? AND FechaBaja is NULL", UsuarioEXT=?, ClaveEXT=?, NuevaPlataforma=1 WHERE DDI=? AND FechaBaja is NULL",
(account.credit, account.active, account.plan == 4, account.postpaid, (credit, account.active, flat_rate, account.postpaid,
account.plan, account.account, account.secret, account.account) account.plan, account.account, account.secret, account.account)
) )
...@@ -71,6 +78,12 @@ def update_sip_accounts() -> 'Tuple[int,int]': ...@@ -71,6 +78,12 @@ def update_sip_accounts() -> 'Tuple[int,int]':
cnx.commit() cnx.commit()
cursor.execute(
'UPDATE [bdd_wifi].[dbo].[TB_ServicioFijo] SET \
TarifaPlana=0, Pospago=0, IdTarifa=0, SaldoActual=0.0\
WHERE FechaBaja is not NULL', (account.active, did)
)
return sip_accounts_updated, did_accounts_updated return sip_accounts_updated, did_accounts_updated
...@@ -80,19 +93,18 @@ def activate_new_plataform(): ...@@ -80,19 +93,18 @@ def activate_new_plataform():
with pyodbc.connect(SQL_SERVER_CNX_STRING) as cnx: with pyodbc.connect(SQL_SERVER_CNX_STRING) as cnx:
with cnx.cursor() as cursor: with cnx.cursor() as cursor:
for sip, account in fully_ported_users(): for user in get_accounts(only_fullyported=True):
user = get_user(sip)
account = account if sip == account else None
cursor.execute( cursor.execute(
'UPDATE [bdd_wifi].[dbo].[TB_ServicioFijo] SET NuevaPlataforma=1 WHERE DDI=?\ 'UPDATE [bdd_wifi].[dbo].[TB_ServicioFijo] SET NuevaPlataforma=1 WHERE DDI=?\
AND FechaBaja is not NULL', AND FechaBaja is NULL',
(sip,) (user.account,)
) )
cursor.execute( cursor.execute(
'UPDATE [bdd_wifi].[dbo].[TB_ServicioFijo] SET ClaveEXT=NULL, SaldoActual=0.0,\ 'UPDATE [bdd_wifi].[dbo].[TB_ServicioFijo] SET ClaveEXT=NULL, SaldoActual=0.0,\
TarifaPlana=0, Pospago=0, IdTarifa=0 WHERE UsuarioEXT is NULL' TarifaPlana=0, Pospago=0, IdTarifa=0 WHERE UsuarioEXT is NULL'
) )
cnx.commit() cnx.commit()
...@@ -104,34 +116,34 @@ def perform_migration(): ...@@ -104,34 +116,34 @@ def perform_migration():
WHERE NuevaPlataforma=1 AND UsuarioEXT != DDI' WHERE NuevaPlataforma=1 AND UsuarioEXT != DDI'
) )
for ddi in migration_targets.fetchall(): for did in migration_targets.fetchall():
ddi = ddi[0] did = did[0]
# Obtención Cuenta MagnusBilling # Obtención Cuenta MagnusBilling
user = get_user(ddi) user = get_user(did)
a2billing_user = a2billing.account_data(ddi) a2billing_user = a2billing.account_data(did)
if user['sip'] == user['username']:
cursor.execute( cursor.execute(
'UPDATE [bdd_wifi].[dbo].[TB_ServicioFijo] SET CuentaA2Billing=?,\ 'UPDATE [bdd_wifi].[dbo].[TB_ServicioFijo] SET CuentaA2Billing=?,\
UsuarioEXT=?, ClaveEXT=?, Activo=?, TarifaPlana=?,Pospago=?,\ UsuarioEXT=?, ClaveEXT=?, Activo=?, TarifaPlana=?,Pospago=?,\
IdTarifa=? WHERE DDI=?', IdTarifa=? WHERE DDI=? AND FechaBaja is NULL',
(a2billing_user['account'] if a2billing_user else None, user['username'], (a2billing_user['account'] if a2billing_user else None, user.account,
user['password'], user['active'], user['offer'] != 0, user['postpaid'], user.secret, user.active, user.offer != 0, user.postpaid,
user['plan'], ddi) user.plan, did))
)
cursor.execute( cursor.execute(
'UPDATE [bdd_wifi].[dbo].[TB_Recargas] SET Cuenta=? WHERE Cuenta=?', 'UPDATE [bdd_wifi].[dbo].[TB_Recargas] SET Cuenta=? WHERE Cuenta=?',
(user['username'], a2billing_user['account'] if a2billing_user else None) (user.account,
a2billing_user['account'] if a2billing_user else None)
) )
else: for user_did in user.dids:
if user_did != user.account:
cursor.execute( cursor.execute(
'UPDATE [bdd_wifi].[dbo].[TB_ServicioFijo] SET CuentaA2Billing=NULL,\ 'UPDATE [bdd_wifi].[dbo].[TB_ServicioFijo] SET CuentaA2Billing=NULL,\
UsuarioEXT=NULL, ClaveEXT=NULL, Activo=?, TarifaPlana=0, Pospago=0,\ UsuarioEXT=NULL, ClaveEXT=NULL, Activo=?, TarifaPlana=0, Pospago=0,\
IdTarifa=0, SaldoActual=0.0 WHERE DDI=?', IdTarifa=0, SaldoActual=0.0 WHERE DDI=? AND FechaBaja is NULL',
(user['active'], ddi) (user.active, user_did)
) )
cnx.commit() cnx.commit()
...@@ -221,10 +233,31 @@ def update_balance() -> Tuple[int, Decimal]: ...@@ -221,10 +233,31 @@ def update_balance() -> Tuple[int, Decimal]:
return accounts, balance return accounts, balance
def update_a2billing_balance():
with pyodbc.connect(SQL_SERVER_CNX_STRING) as cnx:
with cnx.cursor() as cursor:
cursor.execute(
'SELECT DDI, UsuarioEXT FROM [bdd_wifi].[dbo].[TB_ServicioFijo]\
WHERE NuevaPlataforma=0 AND FechaBaja is NULL AND UsuarioEXT is not NULL')
for cli in cursor.fetchall():
account_data = a2billing.account_data(
callerid=cli[0], account=cli[1])
if account_data:
cursor.execute(
'UPDATE [bdd_wifi].[dbo].[TB_ServicioFijo] SET ClaveEXT=?, SaldoActual=?, CuentaA2Billing=? WHERE UsuarioEXT=?',
(account_data['secret'], account_data['credit'],
account_data['account'], account_data['account'])
)
cnx.commit()
else:
pass
def add_cdrs() -> 'list[dict]': def add_cdrs() -> 'list[dict]':
# Obtención de Parámetros # Obtención de Parámetros
sip_accounts = get_sip_accounts(only_postpaid=True) sip_accounts = list(get_accounts(only_postpaid=True))
last_update = get_last_updated_cdr(*[sip.callerid for sip in sip_accounts]) last_update = get_last_updated_cdr(*[sip.callerid for sip in sip_accounts])
cdrs = [] cdrs = []
...@@ -328,7 +361,7 @@ def restore(): ...@@ -328,7 +361,7 @@ def restore():
with pyodbc.connect(SQL_SERVER_CNX_STRING) as cnx: with pyodbc.connect(SQL_SERVER_CNX_STRING) as cnx:
with cnx.cursor() as cursor: with cnx.cursor() as cursor:
cursor.execute( cursor.execute(
'SELECT [UsuarioEXT] FROM [bdd_wifi].[dbo].[TB_ServicioFijo]\ 'SELECT [DDI], [UsuarioEXT] FROM [bdd_wifi].[dbo].[TB_ServicioFijo]\
WHERE NuevaPlataforma=1') WHERE NuevaPlataforma=1')
for username in cursor.fetchall(): for username in cursor.fetchall():
...@@ -340,7 +373,7 @@ def restore(): ...@@ -340,7 +373,7 @@ def restore():
if user and a2billing_account: if user and a2billing_account:
cursor.execute( cursor.execute(
'UPDATE [bdd_wifi].[dbo].[TB_Recargas] SET Cuenta=? WHERE Cuenta=?', 'UPDATE [bdd_wifi].[dbo].[TB_Recargas] SET Cuenta=? WHERE Cuenta=?',
(a2billing_account['account'], user['username']) (a2billing_account['account'], user.account)
) )
cursor.execute( cursor.execute(
...@@ -373,7 +406,7 @@ def restore(): ...@@ -373,7 +406,7 @@ def restore():
if user and a2billing_account: if user and a2billing_account:
cursor.execute( cursor.execute(
'UPDATE [bdd_wifi].[dbo].[TB_Recargas] SET Cuenta=? WHERE Cuenta=?', 'UPDATE [bdd_wifi].[dbo].[TB_Recargas] SET Cuenta=? WHERE Cuenta=?',
(a2billing_account['account'], user['username']) (a2billing_account['account'], user.account)
) )
cursor.execute( cursor.execute(
...@@ -439,6 +472,7 @@ def synchronize(): ...@@ -439,6 +472,7 @@ def synchronize():
activate_new_plataform() activate_new_plataform()
sip_accounts, did_accounts = update_sip_accounts() sip_accounts, did_accounts = update_sip_accounts()
perform_migration() perform_migration()
#update_a2billing_balance()
msg += f'\t- Se han actualizado {typer.style(sip_accounts, fg=typer.colors.GREEN, bold=True)} CLIs y ' msg += f'\t- Se han actualizado {typer.style(sip_accounts, fg=typer.colors.GREEN, bold=True)} CLIs y '
msg += f'{typer.style(did_accounts, fg=typer.colors.BRIGHT_YELLOW, bold=True)} DIDs.' msg += f'{typer.style(did_accounts, fg=typer.colors.BRIGHT_YELLOW, bold=True)} DIDs.'
...@@ -447,12 +481,6 @@ def synchronize(): ...@@ -447,12 +481,6 @@ def synchronize():
msg += f"\n\t- Se han procesado {typer.style(total_refills, fg=typer.colors.GREEN, bold=True)} " msg += f"\n\t- Se han procesado {typer.style(total_refills, fg=typer.colors.GREEN, bold=True)} "
msg += f"recargas con un importe total de {typer.style(f'{amount}€', fg=typer.colors.GREEN, bold=True)}" msg += f"recargas con un importe total de {typer.style(f'{amount}€', fg=typer.colors.GREEN, bold=True)}"
# Actualización de Estado
accounts, balance = update_balance()
update_plan_consumption()
msg += f"\n\t- Se ha actualizado el saldo de {accounts} cuentas, con un saldo total de {typer.style(f'{round(balance,2)}€', fg=typer.colors.GREEN, bold=True)}€."
# Actualización de CDRs # Actualización de CDRs
new_cdrs = add_cdrs() new_cdrs = add_cdrs()
msg += f"\n\t- Se han agregado {len(new_cdrs)} llamadas al CDR." msg += f"\n\t- Se han agregado {len(new_cdrs)} llamadas al CDR."
...@@ -462,7 +490,8 @@ def synchronize(): ...@@ -462,7 +490,8 @@ def synchronize():
@app.command() @app.command()
def test(): def test():
update_sip_accounts() update_a2billing_balance()
if __name__ == "__main__": if __name__ == "__main__":
app() app()
...@@ -27,15 +27,20 @@ DB_CREDENTIALS = { ...@@ -27,15 +27,20 @@ DB_CREDENTIALS = {
class SipAccount: class SipAccount:
def __init__(self, callerid: str, account: str, secret: str, def __init__(self, callerid: str, account: str, secret: str,
credit: float, plan: int, offer: int, active: bool, postpaid: bool) -> None: firstname: str, lastname: str, credit: float,
plan: int, offer: int, active: bool, postpaid: bool,
host: str = None, dids: list = None) -> None:
self.callerid = callerid self.callerid = callerid
self.account = account self.account = account
self.secret = secret self.secret = secret
self.credit = credit self.credit = credit
self.plan = plan self.plan = plan
self.host = host
self.offer = offer self.offer = offer
self.active = active self.active = active
self.postpaid = postpaid self.postpaid = postpaid
self.dids = dids
class MagnusCommandError(Exception): class MagnusCommandError(Exception):
...@@ -196,7 +201,7 @@ def add_balance(phone_number: str, quantity: Decimal, tax: Decimal = Decimal('0. ...@@ -196,7 +201,7 @@ def add_balance(phone_number: str, quantity: Decimal, tax: Decimal = Decimal('0.
raise MagnusCommandError(result.decode('utf-8')) raise MagnusCommandError(result.decode('utf-8'))
def get_user(phone_number: str) -> dict: def get_user(phone_number: str) -> SipAccount:
"""Obtiene los datos de un usuario SIP """Obtiene los datos de un usuario SIP
Args: Args:
...@@ -206,11 +211,13 @@ def get_user(phone_number: str) -> dict: ...@@ -206,11 +211,13 @@ def get_user(phone_number: str) -> dict:
dict: Diccionario con todos los datos. dict: Diccionario con todos los datos.
""" """
if phone_number:
with mariadb.connect(**DB_CREDENTIALS) as cnx: with mariadb.connect(**DB_CREDENTIALS) as cnx:
with cnx.cursor() as cursor: with cnx.cursor() as cursor:
headers = ['sip', 'username', 'password', 'host', 'credit', headers = ['callerid', 'account', 'secret', 'host', 'credit',
'firstname', 'lastname', 'plan', 'offer', 'firstname', 'lastname', 'plan', 'offer',
'active', 'postpaid'] 'active', 'postpaid']
cursor.execute( cursor.execute(
'SELECT s.name, u.username, s.secret password, s.host, u.credit, u.firstname,\ 'SELECT s.name, u.username, s.secret password, s.host, u.credit, u.firstname,\
u.lastname, p.id plan, IFNULL(o.id, 0) offer, u.active active, u.typepaid\ u.lastname, p.id plan, IFNULL(o.id, 0) offer, u.active active, u.typepaid\
...@@ -218,13 +225,26 @@ def get_user(phone_number: str) -> dict: ...@@ -218,13 +225,26 @@ def get_user(phone_number: str) -> dict:
INNER JOIN mbilling.pkg_plan p ON u.id_plan=p.id\ INNER JOIN mbilling.pkg_plan p ON u.id_plan=p.id\
LEFT JOIN mbilling.pkg_offer o ON u.id_offer=o.id\ LEFT JOIN mbilling.pkg_offer o ON u.id_offer=o.id\
INNER JOIN mbilling.pkg_sip s ON u.id=s.id_user\ INNER JOIN mbilling.pkg_sip s ON u.id=s.id_user\
WHERE s.name=?', WHERE s.name=? OR u.username=?',
(phone_number,) (phone_number,phone_number)
) )
query = cursor.fetchone() query = cursor.fetchone()
account = dict(zip(headers, query)) if query else None
if account:
cursor.execute(
'SELECT s.name from pkg_user u INNER JOIN pkg_sip s ON u.id=s.id_user\
WHERE u.username=?',
(account['account'],)
)
account['dids'] = [ddi[0] for ddi in cursor.fetchall()]
else:
account['dids'] = None
else:
account = None
return dict(zip(headers, query)) if query else None return SipAccount(**account) if account else None
def fully_ported_users() -> 'list[tuple]': def fully_ported_users() -> 'list[tuple]':
...@@ -236,7 +256,7 @@ def fully_ported_users() -> 'list[tuple]': ...@@ -236,7 +256,7 @@ def fully_ported_users() -> 'list[tuple]':
completamente migrados a la nueva plataforma, tanto en salidas como llamadas. completamente migrados a la nueva plataforma, tanto en salidas como llamadas.
Returns: Returns:
list[str]: Listado de los CLIs completamente portados. list[str]: Listado de los dids completamente portados.
""" """
with mariadb.connect(**DB_CREDENTIALS) as cnx: with mariadb.connect(**DB_CREDENTIALS) as cnx:
...@@ -246,9 +266,8 @@ def fully_ported_users() -> 'list[tuple]': ...@@ -246,9 +266,8 @@ def fully_ported_users() -> 'list[tuple]':
INNER JOIN mbilling.pkg_cdr c ON c.callerid = u.username\ INNER JOIN mbilling.pkg_cdr c ON c.callerid = u.username\
INNER JOIN mbilling.pkg_trunk t ON c.id_trunk = t.id\ INNER JOIN mbilling.pkg_trunk t ON c.id_trunk = t.id\
INNER JOIN mbilling.pkg_sip s ON s.id_user = u.id\ INNER JOIN mbilling.pkg_sip s ON s.id_user = u.id\
WHERE c.id_trunk is not NULL AND t.trunkcode != \'a2billing\' AND u.active=1\ WHERE u.credit != 0.0 OR (c.id_trunk is not NULL AND t.trunkcode != \'a2billing\')\
GROUP BY s.name ORDER BY u.username') GROUP BY s.name ORDER BY u.username')
data = cursor.fetchall() data = cursor.fetchall()
return data return data
...@@ -260,9 +279,11 @@ def get_plan_consumption(*account: str) -> dict: ...@@ -260,9 +279,11 @@ def get_plan_consumption(*account: str) -> dict:
LEFT JOIN mbilling.pkg_cdr c ON u.id=c.id_user\ LEFT JOIN mbilling.pkg_cdr c ON u.id=c.id_user\
LEFT JOIN mbilling.pkg_offer o ON u.id_offer=o.id\ LEFT JOIN mbilling.pkg_offer o ON u.id_offer=o.id\
WHERE MONTH(c.starttime) >= MONTH(CURRENT_DATE()) AND YEAR(c.starttime)=YEAR(CURRENT_DATE())\ WHERE MONTH(c.starttime) >= MONTH(CURRENT_DATE()) AND YEAR(c.starttime)=YEAR(CURRENT_DATE())\
AND sipiax=0 AND u.id_plan IN(4) AND c.sessionbill=0.0 ' AND sipiax=0 AND u.id_plan IN(4) AND c.sessionbill=0.0'
if len(account): if len(account):
query += f' AND u.username IN ({",".join(*account)}) ' query += f' AND u.username IN ({",".join(*account)}) '
query += 'GROUP BY c.id_user' query += 'GROUP BY c.id_user'
headers = ('consumption', 'max') headers = ('consumption', 'max')
...@@ -373,3 +394,37 @@ def get_sip_accounts(only_postpaid: bool = False) -> 'list[SipAccount]': ...@@ -373,3 +394,37 @@ def get_sip_accounts(only_postpaid: bool = False) -> 'list[SipAccount]':
sip_data = cursor.fetchall() sip_data = cursor.fetchall()
return [SipAccount(*sip) for sip in sip_data] return [SipAccount(*sip) for sip in sip_data]
def get_accounts(only_active: bool = False, only_postpaid: bool = False,
only_fullyported: bool = False):
query = 'SELECT u.username account FROM mbilling.pkg_user u\
INNER JOIN mbilling.pkg_sip s ON s.id_user = u.id\
LEFT JOIN mbilling.pkg_cdr c ON c.callerid = u.username\
LEFT JOIN mbilling.pkg_trunk t ON c.id_trunk = t.id'
if only_active or only_postpaid or only_fullyported:
query += ' WHERE '
restrictions = []
if only_active:
restrictions.append('u.active = 1')
if only_postpaid:
restrictions.append('typepaid=1')
if only_fullyported:
restrictions.append(
'u.credit != 0.0 OR u.id_plan = 4')
query += ' AND '.join(restrictions)
query += ' GROUP BY u.username'
with mariadb.connect(**DB_CREDENTIALS) as cnx:
with cnx.cursor() as cursor:
cursor.execute(query)
for account in cursor.fetchall():
yield get_user(account[0])
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment