# -*- coding: utf-8 -*-

'''
Describe database model for Django

@author: Laurent GAY
@organization: sd-libre.fr
@contact: info@sd-libre.fr
@license: This file is part of Lucterios.

Lucterios is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.

Lucterios is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with Lucterios.  If not, see <http://www.gnu.org/licenses/>.
'''

from __future__ import unicode_literals

from django.utils.translation import gettext_lazy as _

from lucterios.framework.editors import LucteriosEditor
from lucterios.framework.xfercomponents import XferCompButton, XferCompSelect
from lucterios.framework.xferadvance import XferSave, TITLE_DELETE
from lucterios.framework.tools import ActionsManage, FORMTYPE_MODAL, CLOSE_NO, SELECT_SINGLE, FORMTYPE_REFRESH, SELECT_MULTI
from lucterios.framework.error import LucteriosException, IMPORTANT
from lucterios.CORE.parameters import Params
from lucterios.contacts.models import CustomField

from diacamma.accounting.tools import current_system_account
from diacamma.accounting.models import Third, FiscalYear
from diacamma.payoff.editors import SupportingEditor
from diacamma.condominium.models import Set, CallDetail, CallFunds, CallFundsSupporting, Expense, Owner, RecoverableLoadRatio, LIST_DEFAULT_ACCOUNTS, \
    PropertyLot
from diacamma.condominium.system import current_system_condo


class SetEditor(LucteriosEditor):

    def edit(self, xfer):
        revenue_account = xfer.get_components('revenue_account')
        if revenue_account is not None:
            revenue_account.mask = current_system_account().get_revenue_mask()
        secondarykey = xfer.get_components('secondarykey')
        secondarykey.set_select_query(CustomField.objects.filter(modelname=PropertyLot.get_long_name()))
        secondarykey.select_list[0] = ((0, _('general')))
        is_link_to_lots = xfer.get_components('is_link_to_lots')
        is_link_to_lots.java_script = """
var is_link=current.getValue();
parent.get('secondarykey').setVisible(is_link);
parent.get('set_of_lots').setVisible(is_link);
"""

    def show(self, xfer):
        partition = xfer.get_components('partitionfill')
        partition.delete_header('set')
        partition.delete_header('set.budget_txt')
        partition.delete_header('set.sumexpense')
        is_link_to_lots = xfer.get_components('is_link_to_lots')
        if is_link_to_lots.value:
            secondarykey = xfer.get_components('secondarykey')
            if secondarykey.value is None:
                secondarykey.value = _('general')
        else:
            xfer.remove_component('secondarykey')


class OwnerEditor(SupportingEditor):

    def before_save(self, xfer):
        self.item.check_account()
        return SupportingEditor.before_save(self, xfer)

    def saving(self, xfer):
        contact_save = XferSave()
        contact_save.request = xfer.request
        contact_save.item = xfer.item.third.contact.get_final_child()
        contact_save.model = contact_save.item.__class__
        contact_save.params = xfer.params
        contact_save.fill_simple_fields()
        contact_save.fillresponse()

        third_save = XferSave()
        third_save.request = xfer.request
        third_save.item = xfer.item.third.get_final_child()
        third_save.model = third_save.item.__class__
        third_save.params = xfer.params
        third_save.fill_simple_fields()
        third_save.fillresponse()

    def edit(self, xfer):
        if xfer.item.id is None:
            new_account = []
            if Params.getvalue("condominium-old-accounting"):
                new_account.append(Params.getvalue("condominium-default-owner-account"))
            else:
                for num_account in LIST_DEFAULT_ACCOUNTS:
                    new_account.append(Params.getvalue("condominium-default-owner-account%d" % num_account))
            sel = XferCompSelect('third')
            sel.needed = True
            sel.description = _('third')
            sel.set_location(1, 0)
            owner_third_ids = []
            for owner in Owner.objects.all():
                owner_third_ids.append(owner.third_id)
            items = Third.objects.filter(accountthird__code__regex=current_system_account().get_societary_mask()).exclude(id__in=owner_third_ids).distinct()
            items = sorted(items, key=lambda t: str(t))
            sel.set_select_query(items)
            xfer.add_component(sel)
            btn = XferCompButton('add_third')
            btn.set_location(3, 0)
            btn.set_is_mini(True)
            btn.set_action(xfer.request, ActionsManage.get_action_url('accounting.Third', 'Add', xfer), close=CLOSE_NO,
                           modal=FORMTYPE_MODAL, params={'new_account': ';'.join(new_account)})
            xfer.add_component(btn)
            xfer.filltab_from_model(1, xfer.get_max_row() + 1, False, ["information"])
        else:
            old_item = xfer.item
            xfer.item = old_item.third.contact.get_final_child()
            xfer.filltab_from_model(1, 0, False, xfer.item.get_edit_fields())
            CustomField.edit_fields(xfer, 1)

            xfer.item = old_item.third.get_final_child()
            xfer.filltab_from_model(1, xfer.get_max_row() + 1, False, xfer.item.get_edit_fields())
            CustomField.edit_fields(xfer, 1)

            xfer.item = old_item
            xfer.filltab_from_model(1, xfer.get_max_row() + 1, False, ["information"])

    def _show_entryline(self, xfer):
        from diacamma.accounting.views_entries import EntryAccountDel
        link_grid_lines = xfer.get_components('entryline')
        link_grid_lines.description = ''
        link_grid_lines.actions = []
        link_grid_lines.colspan = 2
        link_grid_lines.add_action(xfer.request, ActionsManage.get_action_url('accounting.EntryAccount', 'OpenFromLine', xfer), modal=FORMTYPE_MODAL, unique=SELECT_SINGLE, close=CLOSE_NO)
        link_grid_lines.add_action(xfer.request, EntryAccountDel.get_action(TITLE_DELETE, short_icon='mdi:mdi-delete-outline'), modal=FORMTYPE_MODAL, unique=SELECT_MULTI, close=CLOSE_NO)
        link_grid_lines.add_action(xfer.request, ActionsManage.get_action_url('accounting.EntryAccount', 'Close', xfer), modal=FORMTYPE_MODAL, unique=SELECT_MULTI, close=CLOSE_NO)
        link_grid_lines.add_action(xfer.request, ActionsManage.get_action_url('accounting.EntryAccount', 'Link', xfer), modal=FORMTYPE_MODAL, unique=SELECT_MULTI, close=CLOSE_NO)

    def _show_current_class_loads(self, xfer):
        partition = xfer.get_components('partition')
        partition.actions = []
        partition.description = _("current class loads")
        partition.delete_header('owner')
        xfer.tab = partition.tab
        row = xfer.get_max_row() + 1
        btn = XferCompButton('show_load_count')
        btn.set_location(partition.col, row)
        btn.set_action(xfer.request, ActionsManage.get_action_url('condominium.Owner', 'LoadCount', xfer), modal=FORMTYPE_MODAL, close=CLOSE_NO)
        xfer.add_component(btn)

    def _show_call_payoff(self, xfer):
        callfunds = xfer.get_components('callfunds')
        callfunds.actions = []
        callfunds.colspan = 3
        callfunds.add_action(xfer.request, ActionsManage.get_action_url('condominium.CallFunds', 'Show', xfer), close=CLOSE_NO, unique=SELECT_SINGLE)
        payments = xfer.get_components('payments')
        payments.colspan = 3
        payments.move_action('diacamma.condominium/paymentDel', -1)
        payoff = xfer.get_components('payoff')
        payoff.colspan = 3
        payoff.actions = []
        payoff.description = _('additional payoffs')

    def show(self, xfer):
        xfer.params['supporting'] = self.item.id
        third = xfer.get_components('thirdtotal')
        xfer.tab = third.tab
        btn = XferCompButton('show_third')
        btn.set_location(third.col + third.colspan, third.row)
        act_btn = ActionsManage.get_action_url('accounting.Third', 'Show', xfer)
        if act_btn is not None:
            act_btn.caption = _('third')
        btn.set_action(xfer.request, act_btn, modal=FORMTYPE_MODAL, close=CLOSE_NO, params={'third': self.item.third.id})
        btn.rowspan = 2
        xfer.add_component(btn)

        lots = xfer.get_components('propertylot')
        lots.actions = []
        lots.delete_header('owner')

        if hasattr(xfer.item.third.contact.get_final_child(), 'structure_type'):
            contact = xfer.get_components('ownercontact')
            xfer.tab = contact.tab
            old_item = xfer.item
            xfer.item = old_item.third.contact.get_final_child()
            xfer.filltab_from_model(contact.col, contact.row + 1, True, ['responsability_set'])
            xfer.item = old_item

        self._show_entryline(xfer)
        self._show_current_class_loads(xfer)
        self._show_call_payoff(xfer)

        third_item = xfer.get_components('third')
        xfer.tab = third_item.tab
        self.add_email_status(xfer)


class RecoverableLoadRatioEditor(LucteriosEditor):

    def edit(self, xfer):
        old_account = xfer.get_components("code")
        xfer.remove_component("code")
        sel_code = XferCompSelect("code")
        sel_code.set_location(old_account.col, old_account.row, old_account.colspan + 1, old_account.rowspan)
        existed_codes = []
        for acc_ratio in RecoverableLoadRatio.objects.all():
            existed_codes.append(acc_ratio.code)
        for item in FiscalYear.get_current().chartsaccount_set.all().filter(code__regex=current_system_account().get_expence_mask()).exclude(code__in=existed_codes).order_by('code'):
            sel_code.select_list.append((item.code, str(item)))
        sel_code.set_value(self.item.code)
        xfer.add_component(sel_code)


class PartitionEditor(LucteriosEditor):

    def edit(self, xfer):
        xfer.change_to_readonly('set')
        xfer.change_to_readonly('owner')


class OwnerContactEditor(LucteriosEditor):

    def edit(self, xfer):
        xfer.change_to_readonly('contact')


class CallFundsSupportingEditor(SupportingEditor):
    pass


class PropertyLotEditor(LucteriosEditor):

    def edit(self, xfer):
        xfer.item.mother = True
        CustomField.edit_fields(xfer, 1, 1)
        xfer.move_components('description', 0, 20)
        xfer.move_components('owner', 0, 20)

    def saving(self, xfer):
        LucteriosEditor.saving(self, xfer)
        self.item.set_custom_values(xfer.params)


class CallFundsEditor(LucteriosEditor):

    def before_save(self, xfer):
        if self.item.supporting is not None:
            self.item.supporting.editor.before_save(xfer)

    def edit(self, xfer):
        xfer.change_to_readonly('status')

    def show(self, xfer):
        self.item.check_supporting()
        if (self.item.supporting is not None) and (self.item.status != CallFunds.STATUS_BUILDING):
            old_item = xfer.item
            old_model = xfer.model
            try:
                xfer.item = self.item.supporting
                xfer.model = CallFundsSupporting
                self.item.supporting.editor.show(xfer)
            finally:
                xfer.item = old_item
                xfer.model = old_model
            if Params.getvalue('condominium-payoff-calloffunds') is False:
                xfer.get_components('payoff').actions = []
            self.item.supporting.editor.add_email_status(xfer)
        if self.item.status == CallFunds.STATUS_BUILDING:
            grid = xfer.get_components("calldetail")
            grid.delete_header('total_amount')
            grid.delete_header('owner_part')


class CallDetailEditor(LucteriosEditor):

    def edit(self, xfer):
        type_call = xfer.get_components('type_call')
        type_call.set_select(current_system_condo().get_callfunds_list(complete=False))
        type_call.set_action(xfer.request, xfer.return_action(), close=CLOSE_NO, modal=FORMTYPE_REFRESH)
        set_comp = xfer.get_components('set')
        if int(self.item.type_call) == CallDetail.TYPECALL_EXCEPTIONAL:
            type_load = 1
        else:
            type_load = 0
        set_list = Set.objects.filter(is_active=True, type_load=type_load)
        if len(set_list) == 0:
            raise LucteriosException(IMPORTANT, _('No category of charge defined!'))
        set_comp.set_needed(True)
        set_comp.set_select_query(set_list)
        set_comp.set_action(xfer.request, xfer.return_action(), close=CLOSE_NO, modal=FORMTYPE_REFRESH)
        xfer.get_components('price').prec = Params.getvalue("accounting-devise-prec")
        set_comp.get_json()
        current_set = Set.objects.get(id=set_comp.value)
        if current_set.type_load == Set.TYPELOAD_CURRENT:
            if int(self.item.type_call) == CallDetail.TYPECALL_CURRENT:
                xfer.get_components('price').value = current_set.get_new_current_callfunds()
            elif int(self.item.type_call) == CallDetail.TYPECALL_FUNDFORWORK:
                xfer.get_components('price').value = current_set.get_current_budget() * 0.05
            else:
                xfer.get_components('price').value = 0.0
        elif current_set.type_load == Set.TYPELOAD_EXCEPTIONAL:
            already_called = 0.0
            call_details = CallDetail.objects.filter(set_id=set_comp.value)
            if self.item.id is not None:
                call_details = call_details.exclude(id=self.item.id)
            for detail in call_details:
                already_called += float(detail.price)
            xfer.get_components('price').value = max(0, float(current_set.get_current_budget()) - float(already_called))


class ExpenseEditor(SupportingEditor):

    def edit(self, xfer):
        xfer.change_to_readonly('status')
        if self.item.status == Expense.STATUS_WAITING:
            xfer.change_to_readonly('expensetype')

    def show(self, xfer):
        if self.item.status == Expense.STATUS_BUILDING:
            SupportingEditor.show_third(self, xfer)
            xfer.get_components('date').colspan += 1
            xfer.get_components('expensedetail').colspan += 1
        elif self.item.status != Expense.STATUS_CANCEL:
            SupportingEditor.show(self, xfer)


class ExpenseDetailEditor(LucteriosEditor):

    def edit(self, xfer):
        set_comp = xfer.get_components('set')
        set_comp.set_select_query(Set.objects.filter(is_active=True))
        xfer.get_components('price').prec = Params.getvalue("accounting-devise-prec")
        old_account = xfer.get_components("expense_account")
        xfer.remove_component("expense_account")
        sel_account = XferCompSelect("expense_account")
        sel_account.description = old_account.description
        sel_account.set_location(old_account.col, old_account.row, old_account.colspan, old_account.rowspan)
        for item in FiscalYear.get_current().chartsaccount_set.all().filter(code__regex=current_system_account().get_expence_mask()).order_by('code'):
            sel_account.select_list.append((item.code, str(item)))
        sel_account.set_value(self.item.expense_account)
        xfer.add_component(sel_account)

        self.item.year = FiscalYear.get_current()
        btn = XferCompButton('add_account')
        btn.set_location(old_account.col + 1, old_account.row)
        btn.set_is_mini(True)
        btn.set_action(xfer.request, ActionsManage.get_action_url('accounting.ChartsAccount', 'AddModify', xfer),
                       close=CLOSE_NO, modal=FORMTYPE_MODAL, params={'year': self.item.year.id})
        xfer.add_component(btn)
        xfer.get_components("set").colspan = old_account.colspan + 1
        xfer.get_components("designation").colspan = old_account.colspan + 1
        xfer.get_components("price").colspan = old_account.colspan + 1
