agent.py 7.3 KB
from sqlalchemy import func
from pyramid.view import view_config
from pyramid.httpexceptions import (
    HTTPFound,
    HTTPNotFound,
    )
from pyramid.i18n import TranslationStringFactory
import colander
from deform import (
    Form,
    ValidationFailure,
    Button,
    )
from deform.widget import (
    TextInputWidget,
    CheckboxChoiceWidget,
    )
from ..models import DBSession
from ..models.imgw import (
    Agent,
    Modem,
    ModemPengirim,
    Produk,
    )
from ..tools.msisdn import get_msisdn


_ = TranslationStringFactory('user')


########
# List #
########
@view_config(
    route_name='agent', renderer='templates/agent/list.pt',
    permission='edit-agent')
def view_list(request):
    q = DBSession.query(func.count(Agent.id))
    count = q.scalar()
    q = DBSession.query(Agent).order_by(Agent.jalur, Agent.id)
    return dict(title=_('Agent'), agents=q, count=count)

    
########
# Edit #
########
def get_produk_list():
    r = []
    for row in DBSession.query(Produk).order_by(Produk.nama):
        r.append((row.nama, row.nama))
    return r


def get_produk_set_by_agent(agent):
    r = []
    for row in agent.modem.reply_for:
        r.append(row.produk)
    return set(r) 

            
def get_form(request, class_form):
    schema = class_form()
    #schema = class_form(validator=form_validator)
    schema = schema.bind(produk_list=get_produk_list())
    #schema.request = request
    btn_save = Button('save', _('Simpan'))
    btn_cancel = Button('cancel', _('Batalkan'))
    buttons = (btn_save, btn_cancel)
    return Form(schema, buttons=buttons)
    
def update(agent, values):
    agent.from_dict(values)
    DBSession.add(agent)
    if 'msisdn' not in values:
        return
    q = DBSession.query(Modem).filter_by(imei=agent.id)
    modem = q.first()
    if not modem:
        modem = Modem()
        modem.imei = row.id
    modem.msisdn = get_msisdn(values['msisdn'])
    DBSession.add(modem)
    existing = get_produk_set_by_agent(agent)
    unused = existing - values['pengirim_sms']
    if unused:
        q = DBSession.query(ModemPengirim).filter_by(msisdn=modem.msisdn).\
                filter(ModemPengirim.produk.in_(unused))
        q.delete(synchronize_session=False)
    new = values['pengirim_sms'] - existing
    for produk in new:
        mp = ModemPengirim(produk=produk, msisdn=modem.msisdn)
        DBSession.add(mp)

        
def save_request(values, request, row=None):
    if 'id' in request.matchdict:
        values['id'] = request.matchdict['id']
    row = save_agent(values, request.user, row)
    request.session.flash('%s %s berhasil disimpan.' % (
        row.jalur_ref.nama.title(), row.id))
        

class EditSchema(colander.Schema):
    id = colander.SchemaNode(colander.String(),
            missing=colander.drop,
            widget=TextInputWidget(readonly=True),
            title=_('title-id', default='ID'))
    jenis = colander.SchemaNode(colander.String(),
            missing=colander.drop,
            widget=TextInputWidget(readonly=True),
            title=_('title-jenis', default='Jenis'))
    ket = colander.SchemaNode(colander.String(),
            missing=colander.drop,
            title=_('title-ket', default='Keterangan'),
            description=_(
                'desc-ket', default='Informasi tambahan, misalnya: untuk SMS'))
    url = colander.SchemaNode(colander.String(),
            missing=colander.drop,
            title=_('title-url', default='URL'),
            description=_(
                'desc-url', default='URL im-agent atau im-gw forwarder'))
    
    
@colander.deferred
def deferred_pengirim_sms(node, kw):
    values = kw.get('produk_list', [])
    return CheckboxChoiceWidget(values=values, inline=True)


class ModemSchema(colander.Schema):
    msisdn = colander.SchemaNode(
                colander.String(), title=_('MSISDN'),
                description=_('Nomor HP SIM card'))
    pengirim_sms = colander.SchemaNode(
            colander.Set(), missing=colander.drop,
            widget=deferred_pengirim_sms,
            title=_(
                'title-pengirim-sms', default='Pengirim SMS untuk'),
            description=_(
                'desc-pengirim-sms',
                default='Sistem akan menggunakan informasi ini untuk '\
                'menentukan modem mana yang digunakan untuk mengirim SMS. '\
                'Tujuannya efisiensi pulsa.'))
    ket = colander.SchemaNode(colander.String(),
            missing=colander.drop,
            title=_('title-ket', default='Keterangan'),
            description=_(
                'desc-ket', default='Informasi tambahan, misalnya: untuk SMS'))
    url = colander.SchemaNode(colander.String(),
            missing=colander.drop,
            title=_('title-url', default='URL'),
            description=_(
                'desc-url', default='URL im-agent atau im-gw forwarder'))
                    

def pengirim_sms(agent):
    r = []
    for mp in agent.modem.reply_for:
        r.append(mp.produk)
    return set(r)


@view_config(
    route_name='agent-edit', renderer='templates/agent/edit.pt',
    permission='edit-agent')
def view_edit(request):
    q = DBSession.query(Agent).filter_by(id=request.matchdict['id'])
    agent = q.first()
    if not agent:
        return HTTPNotFound()
    cls = agent.jalur == 1 and ModemSchema or EditSchema    
    form = get_form(request, cls)
    resp = dict(title=_('Edit agent'))
    if not request.POST:
        d = agent.to_dict_without_none()
        if agent.modem:
            d['msisdn'] = agent.modem.msisdn
            d['pengirim_sms'] = pengirim_sms(agent)
        else:
            d['jenis'] = agent.jalur_ref.nama.title()
        resp['form'] = form.render(appstruct=d)
        return resp
    if 'save' not in request.POST:
        return HTTPFound(location=request.route_url('agent'))
    items = request.POST.items()
    try:
        c = form.validate(items)
    except ValidationFailure:
        resp['form'] = form.render()
        return resp
    update(agent, dict(c.items()))
    if agent.modem:
        data = dict(msisdn=agent.modem.msisdn)
        ts = _(
                'modem-apdated', default='Modem ${msisdn} updated',
                mapping=data)
    else:
        data = dict(agent_id=agent.id)
        ts = _('agent-updated', default='Agent ID ${agent_id} updated', mapping=data)
    request.session.flash(ts)
    return HTTPFound(location=request.route_url('agent'))


##########
# Delete #
##########
@view_config(
    route_name='agent-delete', renderer='templates/agent/delete.pt',
    permission='edit-agent')
def view_delete(request):
    q = DBSession.query(Agent).filter_by(id=request.matchdict['id'])
    agent = q.first()
    if not agent:
        return HTTPNotFound()
    btn_delete = Button('delete', _('Delete'))
    btn_cancel = Button('cancel', _('Cancel'))
    buttons = (btn_delete, btn_cancel)
    form = Form(colander.Schema(), buttons=buttons)
    resp = dict(title=_('Delete agent'))
    if not request.POST:
        resp['agent'] = agent
        resp['form'] = form.render()
        return resp
    if 'delete' not in request.POST:
        return HTTPFound(location=request.route_url('agent'))
    agent_id = agent.modem and agent.modem.msisdn or agent.id
    data = dict(agent_id=agent_id)
    ts = _('agent-deleted', default='${agent_id} sudah dihapus', mapping=data)
    q.delete()
    request.session.flash(ts)
    return HTTPFound(location=request.route_url('agent'))