ar_payment.py 10.7 KB
import os
import uuid
#from ..tools import row2dict, xls_reader
from datetime import datetime
from sqlalchemy import not_, func, literal_column
from pyramid.view import (
    view_config,
    )
from pyramid.httpexceptions import (
    HTTPFound,
    )
import colander
from deform import (
    Form,
    widget,
    ValidationFailure,
    )
from ..models import (
    EisDBSession
    )
from ..models import (
    EisSipkdArPayment as ArPayment, EisRekening
    )
    
from ..views import BaseView, ColumnDT, DataTables
from ..tools import dmy_to_date, dmy

SESS_ADD_FAILED = 'Tambah sipkd-ar-payment gagal'
SESS_EDIT_FAILED = 'Edit sipkd-ar-payment gagal'

@colander.deferred
def deferred_chart_type(node, kw):
    values = kw.get('chart_types', [])
    return widget.SelectWidget(values=values)
    
class AddSchema(colander.Schema):
    tanggal = colander.SchemaNode(
                    colander.String(),
                    validator=colander.Length(max=10),
                    oid='tanggal')
    tahun =  colander.SchemaNode(
                    colander.Integer()
             )
             
    kode  = colander.SchemaNode(
                    colander.String(),
                    validator=colander.Length(max=18),
                    oid='kode')
                    
    nama = colander.SchemaNode(
                    colander.String(),
                    validator=colander.Length(max=128),
                    oid = 'nama')
    departemen_kd = colander.SchemaNode(
                    colander.String(),
                    validator=colander.Length(max=128)) 
    departemen_nm = colander.SchemaNode(
                    colander.String(),
                    validator=colander.Length(max=128)) 
    jumlah = colander.SchemaNode(
                    colander.Integer()) 
                    
                    
class EditSchema(AddSchema):
    id = colander.SchemaNode(colander.String(),
            missing=colander.drop,
            widget=widget.HiddenWidget(readonly=True))
            
class view_eis_chart(BaseView):
    ########                    
    # List #
    ########    
    @view_config(route_name='eis-sipkd-ar-payment', renderer='templates/ar-payment/list.pt',
                 permission='read')
    def view_list(self):
        return dict(a={})
        
    ##########                    
    # Action #
    ##########    
    @view_config(route_name='eis-sipkd-ar-payment-act', renderer='json',
                 permission='eis-sipkd-ar-payment-act')
    def act(self):
        ses = self.req.session
        req = self.req
        params = req.params
        url_dict = req.matchdict
        
        if url_dict['act']=='grid':
            columns = []
            columns.append(ColumnDT(ArPayment.id))
            columns.append(ColumnDT(ArPayment.tanggal))
            columns.append(ColumnDT(ArPayment.kode))
            columns.append(ColumnDT(ArPayment.nama))
            columns.append(ColumnDT(ArPayment.jumlah))
            columns.append(ColumnDT(ArPayment.level_id))
            query = EisDBSession.query().select_from(ArPayment)
            rowTable = DataTables(req.GET, query, columns)
            return rowTable.output_result()
    #######    
    # Add #
    #######
    def form_validator(self, form, value):
        if 'id' in form.request.matchdict:
            uid = form.request.matchdict['id']
            q = EisDBSession.query(ArPayment).filter_by(id=uid)
            row = q.first()
        else:
            row = None
                
    def get_form(self, class_form, row=None):
        schema = class_form(validator=self.form_validator)
        schema = schema.bind()
        schema.request = self.req
        if row:
          schema.deserialize(row)
        return Form(schema, buttons=('simpan','batal'))
        
    def save(self, values, user, row=None):
        if not row:
            row = ArPayment()
            row.created = datetime.now()
            row.create_uid = user.id
        row.from_dict(values)
        row.updated = datetime.now()
        row.update_uid = user.id
        row.tanggal = dmy_to_date(values['tanggal']);
        row.aktif = 'aktif' in values and values['aktif'] and 1 or 0
        row.level_id = row.kode.count('.')
        EisDBSession.add(row)
        EisDBSession.flush()
        validate_parent(row.departemen_kd, row.departemen_nm, row.kode, row.tanggal, row.tahun)
        calculate(ArPayment, row.tahun, row.tanggal)
        return row
        
    def save_request(self, values, row=None):
        if 'id' in self.req.matchdict:
            values['id'] = self.req.matchdict['id']
        row = self.save(values, self.req.user, row)
        self.req.session.flash('ArPayment sudah disimpan.')

    def route_list(self):
        return HTTPFound(location=self.req.route_url('eis-sipkd-ar-payment'))
        
    def session_failed(self, session_name):
            
        r = dict(form=self.ses[session_name])
        del self.ses[session_name]
        return r
        
    @view_config(route_name='eis-sipkd-ar-payment-add', renderer='templates/ar-payment/add.pt',
                 permission='eis-sipkd-ar-payment-add')
    def view_add(self):
        req = self.req
        ses = self.ses
        form = self.get_form(AddSchema)
        if req.POST:
            if 'simpan' in req.POST:
                controls = req.POST.items()
                try:
                    controls = form.validate(controls)
                except ValidationFailure as e:
                    req.session[SESS_ADD_FAILED] = e.render()
                    return HTTPFound(location=req.route_url('eis-sipkd-ar-payment-add'))
                self.save_request(dict(controls))
            return self.route_list()
        elif SESS_ADD_FAILED in req.session:
            return self.session_failed(SESS_ADD_FAILED)
        return dict(form=form.render())

        
    ########
    # Edit #
    ########
    def query_id(self):
        return EisDBSession.query(ArPayment).filter_by(id=self.req.matchdict['id'])
        
    def id_not_found(self):    
        msg = 'ArPayment ID %s Tidak Ditemukan.' % self.req.matchdict['id']
        request.session.flash(msg, 'error')
        return route_list()

    @view_config(route_name='eis-sipkd-ar-payment-edt', renderer='templates/ar-payment/add.pt',
                 permission='eis-sipkd-ar-payment-edt')
    def view_edit(self):
        request = self.req
        row = self.query_id().first()
        if not row:
            return id_not_found(request)
        form = self.get_form(EditSchema)
        #form.set_appstruct(rowd)
        if request.POST:
            if 'simpan' in request.POST:
                controls = request.POST.items()
                try:
                    controls = form.validate(controls)
                except ValidationFailure as e:
                    request.session[SESS_EDIT_FAILED] = e.render()               
                    return HTTPFound(location=request.route_url('eis-sipkd-ar-payment-edit',
                                      id=row.id))
                self.save_request(dict(controls), row)
            return self.route_list()
        elif SESS_EDIT_FAILED in request.session:
            return self.session_failed(SESS_EDIT_FAILED)
        values = row.to_dict()
        values['tanggal'] = dmy(row.tanggal)
        return dict(form=form.render(appstruct=values))

    ##########
    # Delete #
    ##########    
    @view_config(route_name='eis-sipkd-ar-payment-del', renderer='templates/ar-payment/delete.pt',
                 permission='eis-sipkd-ar-payment-del')
    def view_delete(self):
        request = self.req
        q = self.query_id()
        row = q.first()
        if not row:
            return self.id_not_found(request)
        form = Form(colander.Schema(), buttons=('hapus','batal'))
        if request.POST:
            if 'hapus' in request.POST:
                msg = 'ArPayment ID %d %s sudah dihapus.' % (row.id, row.nama)
                try:
                  q.delete()
                  EisDBSession.flush()
                except:
                  msg = 'ArPayment ID %d %s tidak dapat dihapus.' % (row.id, row.nama)
                request.session.flash(msg)
            return self.route_list()
        return dict(row=row,
                     form=form.render())

def validate_parent(departemen_kd, departemen_nm, rekening, tanggal, tahun):
    kode = rekening.split('.')
    rekening = "\'" + rekening + "\'"
    rows = EisDBSession.query(EisRekening).\
              filter(literal_column(rekening).like(
                          func.concat(EisRekening.kode,'%'))).all()
    for row in rows:
        if not row.kode:
            continue
        induk = EisDBSession.query(ArPayment).\
                      filter_by(tahun=str(tahun),
                         kode=row.kode.strip(),
                         departemen_kd = departemen_kd.strip(),
                         tanggal = tanggal,
                         ).first()
        if not induk:
            induk = ArPayment()
            induk.tahun = str(tahun)
            induk.kode = row.kode.strip()
            induk.departemen_kd = departemen_kd.strip()
            induk.tanggal = tanggal
        induk.level_id = row.kode.count('.')
        induk.nama = row.nama.strip()
        EisDBSession.add(induk)
        EisDBSession.flush()

def calculate(tabel, tahun, tanggal=None):
    query = EisDBSession.query(tabel).filter_by(tahun = str(tahun)).\
            order_by(tabel.departemen_kd, tabel.tanggal, tabel.kode.desc())
    if tanggal:
        query = query.filter_by(tanggal=tanggal)
    
    old_level = 0
    levels = {}
    jumlahs = {}
    key = ""
    for row in query.all():
        if row.level_id > old_level:
            print('Lebih', jumlahs, key)
            old_level = row.level_id
            key = 'a'+str(row.level_id)
            
        #JIKA level sama dengan sebelumnya jumlahkan
        if row.level_id == old_level:
            print('Sama')
            if not key in jumlahs:
                jumlahs[key] = row.jumlah
            else:
                jumlahs[key] += row.jumlah
                
        #JIKA level < sebelumnya update current row
        if row.level_id < old_level:
            print('Kurang', jumlahs, key)
            print('kode: ', row.kode, 'level: ', row.level_id, 'old: ', old_level, 'key: ', key, 'jml: ', row.jumlah, 'jmls: ', jumlahs)
            row.jumlah = jumlahs[key]
            EisDBSession.add(row)
            EisDBSession.flush()
            jumlahs[key] = 0 #key sebelumnya diset jadi 0 
            key = 'a'+str(row.level_id)
            if not key in jumlahs:
                jumlahs[key] = row.jumlah
            else:
                jumlahs[key] += row.jumlah
            old_level = row.level_id
            print('kode: ', row.kode, 'level: ', row.level_id, 'old: ', old_level, 'key: ', key, 'jml: ', row.jumlah, 'jmls: ', jumlahs)