ranking_opd.py 9.56 KB
import pytz    
import transaction
import colander
from datetime import datetime, date
from email.utils import parseaddr
from pyramid.view import view_config
from pyramid.httpexceptions import (HTTPFound, HTTPForbidden, HTTPNotFound)
from pyramid.security import (remember, forget, authenticated_userid,)
from deform import (Form, ValidationFailure, widget,)
from ..tools import dmy, date_from_str, int_to_roman
from sqlalchemy import func, and_, case

from ..models import (DBSession, User,)
from ..models.isipkd import(
      ARSspd, ARInvoice, Unit, Rekening, Anggaran
      )
from pyramid.view import notfound_view_config
import logging
log = logging.getLogger(__name__)

    
###########
# Ranking #
###########
@view_config(route_name='ranking', renderer='templates/ranking/ranking_opd.pt')
def view_rank(request):
    statusadmin = False
    if hasattr(request.user,'groups'):
        for g in request.user.groups:
            if g.group_name=='admin':
                statusadmin = True
                break
    if statusadmin == True:
        if 'date' in request.params and request.params['date']:
            now = date_from_str(request.params['date'].strip())
        else:
            now = date.today()
        dates = dict(
                    year = now.year,
                    month = now.month,
                    week = int(now.strftime('%W')),
                    day = now,
                )
        data_dashboard = dict(
                        sopd = [], ## Ranking Penerimaan
                        sopd10 = [], ## 10 Ranking Penerimaan
                        sopd4 = []
                    )

        #Unit
        opds = Unit.query().filter(Unit.level_id.between(3,4)).order_by(Unit.kode).all()
        for op in opds:
            if op.level_id==3:
                data_dashboard['sopd'].append(dict(peringkat=0,kode=op.kode.strip(), level=op.level_id, unit=op.nama.strip(), nominal=0, target=0, persen=0))
            if op.level_id==4:
                data_dashboard['sopd4'].append(dict(kode=op.kode.strip(), level=op.level_id, unit=op.nama.strip(), nominal=0, target=0, persen=0))
            
        ##RANKING##
        tanggal_berjalan = dates['day']
        tahun_berjalan = tanggal_berjalan.year
        opd = DBSession.query(
                        func.sum(ARSspd.bayar).label('jumlah'),
                        func.max(func.trim(Unit.kode)).label('kode'),
                        func.max(func.trim(Unit.nama)).label('nama'),
                        func.max(Unit.level_id).label('level_id'),
                ).join(ARInvoice, ARInvoice.id == ARSspd.arinvoice_id).\
                  join(Unit, func.trim(Unit.kode) == func.trim(ARInvoice.unit_kode)).\
                filter(ARSspd.tahun_id==tahun_berjalan,
                       Unit.level_id>=3).\
                group_by(func.trim(Unit.kode)).all()
        for sopd in opd:
            if sopd.level_id>=3:
                for unit3 in data_dashboard['sopd']:
                    if sopd.kode.startswith(unit3['kode']):
                        unit3['nominal']+=sopd.jumlah
            if sopd.level_id>=4:
                for unit4 in data_dashboard['sopd4']:
                    if sopd.kode.startswith(unit4['kode']):
                        unit4['nominal']+=sopd.jumlah
        #QUERY INVOICE
        # invoices = DBSession.query(
                        # ARInvoice.tgl_tetap.label('tanggal'),
                        # ARInvoice.jumlah.label('jumlah'),
                        # ARInvoice.rek_kode.label('rek_kode'),
                        # Unit.kode.label('kode'),
                        # Unit.nama.label('nama'),
                # ).join(Unit, func.trim(Unit.kode) == func.trim(ARInvoice.unit_kode)).\
                # filter(ARInvoice.tahun_id==dates['year']).order_by(ARInvoice.unit_kode)\
                # .all()
        invoices = DBSession.query(
                        case([
                          (Anggaran.perubahan > 0, 
                           func.coalesce(Anggaran.perubahan,0))
                          ],
                        else_= func.coalesce(Anggaran.murni,0)).label('jumlah'), 
                        func.trim(Rekening.kode).label('rek_kode'),
                        Anggaran.kode.label('kode'),
                        Anggaran.nama.label('nama'),
                ).join(Rekening, Rekening.id == Anggaran.rekening_id).\
                filter(Anggaran.tahun==dates['year']).order_by(Anggaran.kode)\
                .all()
        for i in invoices:
            #RANKING Target
            for unit3 in data_dashboard['sopd']:
                if i.kode.strip().startswith(unit3['kode']):
                    unit3['target']+=i.jumlah
        ##RANKING Persen
        for unit3 in data_dashboard['sopd']:
            unit3['persen'] = unit3['target']>0 and str(round((float(unit3['nominal'])/float(unit3['target']))*100,2)) or '0'
                        
        ##SORT
        data_dashboard['sopd'] = sorted(data_dashboard['sopd'], key = lambda i: (i['nominal']), reverse=True)
        i=-1
        for opd in data_dashboard['sopd']:
            i+=1
            if i < 10:
                data_dashboard['sopd10'].append(dict(peringkat=i+1, kode=opd['kode'], unit=opd['unit'], nominal=opd['nominal'], target=opd['target'], persen=opd['persen']))
            opd['peringkat'] = i+1
            

        return dict(project='esipkd', dates=dates, data = data_dashboard, statusadmin=statusadmin)
    else:
        return dict(project='esipkd', statusadmin=statusadmin)

@view_config(route_name='ranking-det', renderer='templates/ranking/ranking_det.pt')
def view_det(request):
    params = request.params
    url_dict = request.matchdict
    found = False
    row = ''
    now = date.today()
    statusadmin = False
    if hasattr(request.user,'groups'):
        for g in request.user.groups:
            if g.group_name=='admin':
                statusadmin = True
                break
    if statusadmin == True:
        if 'date' in request.params and request.params['date']:
            now = date_from_str(request.params['date'].strip())
        else:
            now = date.today()
        dates = dict(
                    year = now.year,
                    month = now.month,
                    week = int(now.strftime('%W')),
                    day = now,
                ) 
        data_dashboard = dict(
                        sopd4 = []
                    )
        level = DBSession.query(Unit.level_id).filter(func.trim(Unit.kode)==params['kode']).scalar()
        opds = DBSession.query(Unit).filter(Unit.level_id==(level+1),
                                            Unit.kode.ilike(params['kode']+'%'))\
                                     .order_by(Unit.kode).all()
        if not opds:
            raise HTTPFound(location=request.route_url('home'))
        for op in opds:
            data_dashboard['sopd4'].append(dict(kode=op.kode.strip(), level=op.level_id, unit=op.nama.strip(), nominal=0, target=0, persen=0))

        unit_kode = 'kode' in params and params['kode'] or ''
        unit_nama = 'unit' in params and params['unit'] or ''
        tanggal_berjalan = dates['day']
        tahun_berjalan = tanggal_berjalan.year
        opd = DBSession.query(
                        func.sum(ARSspd.bayar).label('jumlah'),
                        func.max(func.trim(Unit.kode)).label('kode'),
                        func.max(func.trim(Unit.nama)).label('nama'),
                        func.max(Unit.level_id).label('level_id'),
                ).join(ARInvoice, ARInvoice.id == ARSspd.arinvoice_id).\
                  join(Unit, func.trim(Unit.kode) == func.trim(ARInvoice.unit_kode)).\
                filter(ARSspd.tahun_id==tahun_berjalan).\
                group_by(func.trim(Unit.kode)).all()
        for sopd in opd:
            for unit4 in data_dashboard['sopd4']:
                if sopd.kode.startswith(unit4['kode']):
                    unit4['nominal']+=sopd.jumlah
        #QUERY INVOICE
        # invoices = DBSession.query(
                        # ARInvoice.tgl_tetap.label('tanggal'),
                        # ARInvoice.jumlah.label('jumlah'),
                        # ARInvoice.rek_kode.label('rek_kode'),
                        # Unit.kode.label('kode'),
                        # Unit.nama.label('nama'),
                # ).join(Unit, func.trim(Unit.kode) == func.trim(ARInvoice.unit_kode)).\
                # filter(ARInvoice.tahun_id==dates['year']).order_by(ARInvoice.unit_kode)\
                # .all()
        invoices = DBSession.query(
                        case([
                          (Anggaran.perubahan > 0, 
                           func.coalesce(Anggaran.perubahan,0))
                          ],
                        else_= func.coalesce(Anggaran.murni,0)).label('jumlah'), 
                        func.trim(Rekening.kode).label('rek_kode'),
                        Anggaran.kode.label('kode'),
                        Anggaran.nama.label('nama'),
                ).join(Rekening, Rekening.id == Anggaran.rekening_id).\
                filter(Anggaran.tahun==dates['year']).order_by(Anggaran.kode)\
                .all()
        for i in invoices:
            #RANKING Target
            for unit4 in data_dashboard['sopd4']:
                if i.kode.strip().startswith(unit4['kode']):
                    unit4['target']+=i.jumlah
        ##RANKING Persen
        for unit4 in data_dashboard['sopd4']:
            unit4['persen'] = unit4['target']>0 and str(round((float(unit4['nominal'])/float(unit4['target']))*100,2)) or '0'

        return dict(project='esipkd', dates=dates, data = data_dashboard, unit_kode=unit_kode, unit_nama=unit_nama, statusadmin=statusadmin)
    else:
        return dict(project='esipkd', statusadmin=statusadmin)