# -*- coding: utf-8 -*-
##############################################################################
#
#    datenpol gmbh
#    Copyright (C) 2013-TODAY datenpol gmbh ()
#
#    This program is free software: you can redistribute it and/or modify
#    it under the terms of the GNU Affero General Public License as
#    published by the Free Software Foundation, either version 3 of the
#    License, or (at your option) any later version.
#
#    This program 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 Affero General Public License for more details.
#
#    You should have received a copy of the GNU Affero General Public License
#    along with this program.  If not, see .
#
##############################################################################
import requests
import json
from odoo import tools, api, fields, models, _
from odoo.exceptions import ValidationError
from odoo.addons.queue_job.job import job
from odoo.addons.component.core import Component
class PartnerEventListener(Component):
    _name = 'res.partner.listener'
    _inherit = 'base.event.listener'
    _apply_on = ['res.partner']
    def on_record_write(self, record, fields=None):
        if record.active and record.portal_id:
            if 'property_product_pricelist' in fields:
                for contact in record.child_ids:
                    self.env['res.partner'].with_delay().job_export_portal_price(contact)
            if 'parent_id' in fields:
                self.env['res.partner'].with_delay().job_export_portal_price(record)
class Partner(models.Model):
    _name = 'res.partner'
    _inherit = ['res.partner', 'dp_custom.helper']
    company = fields.Char(string='Unternehmen')
    info_kundennr = fields.Char(string='Info-Kundennr.')
    info_uid = fields.Char(string='Info-UID')
    endkunde = fields.Boolean(string='Endkunde', help='Beschreibt, ob es ein Endkunde ist')
    line_ids = fields.Many2many(comodel_name='res.line', string='Produktionslinien')
    portal_id = fields.Char(string='Portal-ID')
    partner_sector_id = fields.Many2one(comodel_name='res.partner.sector', string='Branche')
    active = fields.Boolean(track_visibility='onchange')
    portal_export_pending = fields.Boolean(string='Portal Export ausständig')
    date_vat_check = fields.Date(string='Datum der letzten UID-Prüfung')
    _sql_constraints = [
        ('ref_uniq', 'unique(ref)', 'Die Interne Referenz muss eindeutig sein'),
        ('portal_id_uniq', 'unique(portal_id)', 'Die Portal-ID muss eindeutig sein')
    ]
    @api.model
    def portal_create_partner(self, vals):
        vals = self.with_context(sst_1=True).remove_not_specified_fields(vals)
        vals = self.correct_values(vals)
        if not vals.get('active', False):
            vals['active'] = False
        self.create(vals)
        return True
    @api.model
    def pg_create_company(self, vals):
        vals = self.with_context(sst_11=True).remove_not_specified_fields(vals)
        vals = self.correct_values(vals)
        partner = self.with_context(active_test=False).search([('ref', '=', vals['ref'])])
        if partner:
            if not partner.is_company:
                raise ValidationError(
                    _("Der Partner mit der Internen Referenz '%s' ist kein Unternehmen" % vals['ref']))
            partner.write(vals)
        else:
            if not vals.get('is_company', False):
                vals['is_company'] = True
            partner = self.create(vals)
            partner.property_account_fiscal_position = self.env['account.fiscal.position'].get_fiscal_position(
                partner.id)
        return True
    @api.model
    def correct_values(self, vals):
        if vals.get('country_id', False):
            country = self.env['res.country'].search([('code', '=', vals['country_id'])])
            if country:
                vals['country_id'] = country.id
            else:
                raise ValidationError(
                    _("Das Land mit dem ISO-Code \'%s\' kann nicht zugeordnet werden" % vals['country_id']))
        if vals.get('line_ids', False):
            line_ids = self.env['res.line'].search([('name', 'in', vals['line_ids'])])
            if line_ids:
                vals['line_ids'] = [(6, 0, line_ids.ids)]
            else:
                raise ValidationError(
                    _("Die Produktionslinie mit dem Code \'%s\' kann nicht zugeordnet werden" % vals['line_ids']))
        if vals.get('lang', False):
            temp = vals['lang']
            vals['lang'] = False
            for selection in self.fields_get('lang')['lang']['selection']:
                if selection[0].startswith(temp):
                    vals['lang'] = selection[0]
                    break
            if not vals['lang']:
                raise ValidationError(_("Die Sprache mit dem Code \'%s\' kann nicht zugeordnet werden" % temp))
        if vals.get('partner_sector_id', False):
            branche = self.env['res.partner.sector'].search(
                [('name', '=', vals['partner_sector_id'])])
            if branche:
                vals['partner_sector_id'] = branche.id
            else:
                raise ValidationError(_("Die Branche \'%s\' kann nicht zugeordnet werden" % vals['partner_sector_id']))
        if vals.get('property_payment_term_id', False):
            payment_term = self.env['account.payment.term'].search(
                [('code', '=', vals['property_payment_term_id'])])
            if payment_term:
                vals['property_payment_term_id'] = payment_term.id
            else:
                raise ValidationError(_("Die Zahlungsbedingung mit dem Code \'%s\' kann nicht zugeordnet werden" % vals[
                    'property_payment_term_id']))
        if vals.get('property_product_pricelist', False):
            product_pricelist = self.env['product.pricelist'].search(
                [('currency_id.name', '=', vals['property_product_pricelist'])])
            if product_pricelist:
                vals['property_product_pricelist'] = product_pricelist[0].id
            else:
                raise ValidationError(_("Die Preisliste mit der Währung \'%s\' kann nicht zugeordnet werden" % vals[
                    'property_product_pricelist']))
        if vals.get('retail_partner_id', False):
            retail_partner = self.env['res.partner'].search(
                [('ref', '=', vals['retail_partner_id'])])
            if retail_partner:
                vals['retail_partner_id'] = retail_partner.id
            else:
                raise ValidationError(_("Der Händler mit der Internen Referenz \'%s\' kann nicht zugeordnet werden" % vals[
                    'retail_partner_id']))
        return vals
    @api.model
    def _get_specified_fields(self):
        common_list = ['street', 'street2', 'zip', 'city', 'country_id', 'fax', 'phone', 'mobile',
                       'endkunde', 'line_ids', 'lang', 'portal_id', 'email', 'opt_out']
        if self.env.context.get('sst_1', False):
            common_list.extend(['firstname', 'lastname', 'midname', 'company', 'info_kundennr', 'info_uid'])
            return common_list
        elif self.env.context.get('sst_11', False):
            common_list.extend(['name', 'ref', 'partner_sector_id', 'comment', 'vat', 'property_payment_term_id',
                                'property_pricelist_id', 'date_vat_check', 'active', 'property_product_pricelist',
                                'retail_partner_id'])
            return common_list
        else:
            return super(Partner, self)._get_specified_fields()
    @api.model
    def cron_export_portal_prices(self):
        partners = self.search([('portal_export_pending', '=', True), ('company_id', '=', self.env.user.company_id.id)])
        for partner in partners:
            self.with_delay().job_export_portal_price(partner)
            partner.portal_export_pending = False
    @api.multi
    @job
    def job_export_portal_price(self, partner_id):
        if not partner_id.portal_id:
            raise ValidationError(_("Der Partner mit der ID %s hat keine Portal-ID" % partner_id.id))
        pricelist = partner_id.property_product_pricelist
        data = []
        for item in pricelist.item_ids:
            if item.compute_price == 'percentage' and item.applied_on in ['3_global', '2_product_category',
                                                                          '1_product']:
                code = False
                if item.applied_on == '2_product_category':
                    code = item.categ_id.code
                if item.applied_on == '1_product':
                    code = item.product_tmpl_id.default_code
                data.append({
                    'customer_id': partner_id.portal_id,
                    'code': code,
                    'discount': 1 - (item.percent_price / 100)
                })
                portal_url = tools.config.get('portal_url')
                application_id = tools.config.get('portal_secret')
                response = requests.post(portal_url + '/api/v1/set-discounts/?secret=' + application_id,
                                         data=json.dumps(data))
                if response.status_code != 200:
                    raise ValidationError(_('Rabatt konnte nicht gesetzt werden.'))
class PartnerSector(models.Model):
    _name = 'res.partner.sector'
    _description = 'Branche'
    _order = 'id,name'
    name = fields.Char(string='Bezeichnung', required=True)
    sequence = fields.Integer(string='Sequenz')
    _sql_constraints = [
        ('name_uniq', 'unique(name)', 'Die Bezeichnung muss eindeutig sein')
    ]