<gh_stars>0
import json
from datetime import date
from dateutil.relativedelta import relativedelta
from flask import request
from app.dao.agent import get_agent
from app.dao.dashboard import get_user_data_content
from app.dao.headrent import get_headrent, get_headrent_row, get_headrents, get_headrents_ids, get_landlord_id, \
    post_headrent, post_hr_alloc
from app.dao.money import get_acc_id
from app.main.common import inc_date_m
from app.dao.rent import get_idlist_recent
from app.main.dashboard import mpost_recent_headrent, mpost_search
from app.dao.money import get_cat_id, post_money_item
from app.main.functions import money, strToDec
from app.main.rent import mget_paidtodate, get_rent_gale
from app.models import Agent, Headrent, HeadrentAlloc, MoneyItem
from app.modeltypes import AdvArr, Freqs, HrStatuses, Tenures
from sqlalchemy import func


def create_headrent_filter(fdict):
    filtr = []
    if fdict.get('rentcode'):
        filtr.append(Headrent.code.startswith([fdict.get('rentcode')]))
    if fdict.get('propaddr'):
        filtr.append(Headrent.propaddr.ilike('%{}%'.format(fdict.get('propaddr'))))
    if fdict.get('agentdetail'):
        filtr.append(Agent.detail.ilike('%{}%'.format(fdict.get('agentdetail'))))
    if fdict.get('status') and fdict.get('status') != ["all statuses"]:
        ids = []
        for i in range(len(fdict.get('status'))):
            ids.append(HrStatuses.get_id(fdict.get('status')[i]))
            filtr.append(Headrent.status_id.in_(ids))
    if fdict.get('nextrentdate') and fdict.get('nextrentdate') != '':
        filtr.append(func.lulu.next_rent_date(Headrent.id, 2) <= fdict.get('nextrentdate'))
    return filtr


def create_new_headrent():
    # create new headrent function not yet built, so return any id:
    return 23


def mget_headrent(headrent_id):
    headrent = get_headrent(headrent_id)
    mpost_recent_headrent(headrent_id)
    headrent.status = HrStatuses.get_name(headrent.status_id)
    headrent.tenuredet = Tenures.get_name(headrent.tenure_id)
    headrent.advarrdet = AdvArr.get_name(headrent.advarr_id)
    headrent.rent_type = "rent charge" if headrent.tenuredet == "rentcharge" else "ground rent"
    headrent.paidtodate = mget_paidtodate(headrent.advarrdet, headrent.arrears, headrent.datecode_id, headrent.freq_id,
                                          headrent.lastrentdate, headrent.rentpa)
    headrent.nextrentdate = inc_date_m(headrent.lastrentdate, headrent.freq_id, headrent.datecode_id, 1)
    headrent.pay_from_date = headrent.paidtodate + relativedelta(days=1)
    headrent.rent_gale = get_rent_gale(headrent.nextrentdate, headrent.freq_id, headrent.rentpa)

    return headrent


def mget_headrents(filtr):
    headrents = get_headrents(filtr)
    for headrent in headrents:
        headrent.status = HrStatuses.get_name(headrent.status_id)
        headrent.nextrentdate = inc_date_m(headrent.lastrentdate, headrent.freq_id, headrent.datecode_id, 1)
    return headrents


def mget_headrents_dict():
    return {'agentdetail': request.form.get('agentdetail') or '',
            'nextrentdate': request.form.get('nextrentdate') or '',
            'propaddr': request.form.get('propaddr') or '',
            'rentcode': request.form.get('rentcode') or '',
            'status': request.form.getlist('status') or ['active']}
    # dateToStrJson(date.today() + relativedelta(days=35))}


def mget_headrents_filter():
    fdict = mget_headrents_dict()
    filtr = create_headrent_filter(fdict)
    return fdict, filtr


def mget_headrents_filter_from_dash(search_id):
    fdict = json.loads(get_user_data_content(search_id))
    filtr = create_headrent_filter(fdict)
    return fdict, filtr


def mget_headrents_default():
    filtr = [Headrent.status_id == 1]
    fdict = {'rentcode': '', 'propaddr': '', 'agentdetail': '', 'status': ['active'],
             'nextrentdate': ''}
    headrents = mget_headrents(filtr)

    return fdict, headrents


def mget_headrents_from_dash(search_id):
    fdict, filtr = mget_headrents_filter_from_dash(search_id)
    # If the search dictionary is not in the recent_search table we post it
    headrents = mget_headrents(filtr)
    return fdict, headrents


def mget_headrents_from_search():
    fdict, filtr = mget_headrents_filter()
    # If the search dictionary is not in the recent_search table we post it
    mpost_search(fdict, 'headrent')
    headrents = mget_headrents(filtr)
    return fdict, headrents


def mget_headrents_ids(headrent_id):
    ids = json.loads(request.form.get("headrent_id_list")) if headrent_id == 0 else [headrent_id,]
    headrents = get_headrents_ids(ids)
    agent_id = headrents[0].agent_id
    total = 0
    agentcode_pass = True
    for headrent in headrents:
        if headrent.agent_id != agent_id:
            agentcode_pass = False
            break
        headrent.advarrdet = AdvArr.get_name(headrent.advarr_id)
        headrent.paidtodate = mget_paidtodate(headrent.advarrdet, headrent.arrears, headrent.datecode_id,
                                              headrent.freq_id,
                                              headrent.lastrentdate, headrent.rentpa)
        headrent.nextrentdate = inc_date_m(headrent.lastrentdate, headrent.freq_id, headrent.datecode_id, 1)
        headrent.pay_from_date = headrent.paidtodate + relativedelta(days=1)
        headrent.pay_to_date = inc_date_m(headrent.nextrentdate, headrent.freq_id, headrent.datecode_id, 1) \
            if headrent.advarrdet == "in advance" else headrent.nextrentdate
        headrent.rent_gale = get_rent_gale(headrent.nextrentdate, headrent.freq_id, headrent.rentpa)
        total += headrent.arrears + headrent.rent_gale
    agent = get_agent(agent_id)

    return agent, agentcode_pass, headrents, total


def mget_headrents_recent_filter():
    list = get_idlist_recent("recent_headrents")
    filtr = [Headrent.id.in_(list)]
    return filtr, list


def mpay_headrents(hr_payment_id):
    money_item = MoneyItem()
    money_item.date = date.today()
    money_item.payer = request.form.get("payee")
    money_item.amount = -money(request.form.get("total"))
    paytype = request.form.get("paytype")
    money_item.memo = "headrent paid by " + paytype
    money_item.cleared = 0 if paytype == 'cheque' else 1
    money_item.cat_id = get_cat_id('head rent')
    acc_desc = request.form.get("acc_desc")
    acc_id = get_acc_id(acc_desc)
    money_item.acc_id = acc_id
    money_item_id = post_money_item(money_item)
    print(request.form)
    zipped = zip(request.form.getlist('hr_id'), request.form.getlist('arrears'), request.form.getlist('rent_gale'))
    posts = list(zipped)
    for id, arrears, rent_gale in posts:
        print(id, arrears, rent_gale)
        hr_id = int(id)
        headrent = mget_headrent(hr_id)
        headrent.arrears = 0
        headrent.lastrentdate = inc_date_m(headrent.lastrentdate, headrent.freq_id, headrent.datecode_id, 1)
        hr_alloc = HeadrentAlloc()
        hr_alloc.allocation = money(arrears) + money(rent_gale)
        hr_alloc.landlord_id = get_landlord_id(hr_id)
        hr_alloc.headrent_id = hr_id
        hr_alloc.money_item_id = money_item_id
        hr_alloc.hr_payment_id = hr_payment_id
        post_hr_alloc(hr_alloc)
        _ = post_headrent(headrent)
    return


def update_headrent(headrent_id):
    headrent = get_headrent_row(headrent_id)
    headrent.advarr_id = request.form.get("advarr")
    headrent.arrears = strToDec(request.form.get("arrears"))
    headrent.code = request.form.get("rentcode")
    # we need code to generate datecode_id from lastrentdate with user choosing sequence:
    # headrent.datecode_id = int(request.form.get("datecode_id"))
    headrent.freq_id = Freqs.get_id(request.form.get("frequency"))
    headrent.lastrentdate = request.form.get("lastrentdate")
    headrent.reference = request.form.get("reference")
    headrent.rentpa = strToDec(request.form.get("rentpa"))
    headrent.salegrade_id = request.form.get("salegrade")
    headrent.source = request.form.get("source")
    headrent.status_id = request.form.get("status")
    headrent.tenantname = request.form.get("tenantname")
    headrent.tenure_id = request.form.get("tenure")
    headrent_id = post_headrent(headrent)

    return  headrent_id


def update_landlord(headrent_id, landlord_id):
    headrent = get_headrent_row(headrent_id)
    headrent.landlord_id = landlord_id
    headrent_id = post_headrent(headrent)

    return  headrent_id


def update_note(headrent_id, note):
    headrent = get_headrent_row(headrent_id)
    headrent.note = note
    headrent_id = post_headrent(headrent)

    return headrent_id


def update_propaddr(headrent_id, propaddr):
    headrent = get_headrent_row(headrent_id)
    headrent.propaddr = propaddr
    headrent_id = post_headrent(headrent)

    return headrent_id
