<commit_before># -*- coding: utf-8 -*-
##############################################################################
#
#    OpenERP, Open Source Management Solution
#    Copyright (C) 2004-2009 Tiny SPRL (<http://tiny.be>).
#
#    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 <http://www.gnu.org/licenses/>.
#
##############################################################################

from odoo import fields, osv, models, api
import logging
from .meli_oerp_config import *

from ..melisdk.meli import Meli

import json

import logging
_logger = logging.getLogger(__name__)

from . import posting
from . import product
from . import shipment
from dateutil.parser import *
from datetime import *
from urllib.request import urlopen
import requests
try:
    from urllib import urlencode
except ImportError:
    from urllib.parse import urlencode

from . import versions
from .versions import *

class sale_order_line(models.Model):
    _inherit = "sale.order.line"

    meli_order_item_id = fields.Char('Meli Order Item Id')
    meli_order_item_variation_id = fields.Char('Meli Order Item Variation Id')

sale_order_line()

class sale_order(models.Model):
    _inherit = "sale.order"

    meli_order_id =  fields.Char(string='Meli Order Id',index=True)
    meli_orders = fields.Many2many('mercadolibre.orders',string="ML Orders")
    meli_status = fields.Selection( [
        #Initial state of an order, and it has no payment yet.
                                        ("confirmed","Confirmado"),
        #The order needs a payment to become confirmed and show users information.
                                      ("payment_required","Pago requerido"),
        #There is a payment related with the order, but it has not accredited yet
                                    ("payment_in_process","Pago en proceso"),
        #The order has a related payment and it has been accredited.
                                    ("paid","Pagado"),
        #The order has a related partial payment and it has been accredited.
                                    ("partially_paid","Parcialmente Pagado"),
        #The order has not completed by some reason.
                                    ("cancelled","Cancelado")], string='Order Status');

    meli_status_detail = fields.Text(string='Status detail, in case the order was cancelled.')
    meli_date_created = fields.Datetime('Creation date')
    meli_date_closed = fields.Datetime('Closing date')

#        'meli_order_items': fields.one2many('mercadolibre.order_items','order_id','Order Items' ),
#        'meli_payments': fields.one2many('mercadolibre.payments','order_id','Payments' ),
    meli_shipping = fields.Text(string="Shipping")

    meli_total_amount = fields.Float(string='Total amount')
    meli_shipping_cost = fields.Float(string='Shipping Cost',help='Gastos de envío')
    meli_shipping_list_cost = fields.Float(string='Shipping List Cost',help='Gastos de envío, costo de lista/interno')
    meli_paid_amount = fields.Float(string='Paid amount',help='Paid amount (include shipping cost)')
    meli_fee_amount = fields.Float(string='Fee amount',help="Comisión")
    meli_currency_id = fields.Char(string='Currency ML')
#        'buyer': fields.many2one( "mercadolibre.buyers","Buyer"),
#       'meli_seller': fields.text( string='Seller' ),
    meli_shipping_id =  fields.Char('Meli Shipping Id')
    meli_shipment = fields.Many2one('mercadolibre.shipment',string='Meli Shipment Obj')
    meli_shipment_logistic_type = fields.Char(string="Logistic Type",index=True)

    def action_confirm(self):
        _logger.info("meli order action_confirm: " + str(self.mapped("name")) )
        res = super(sale_order,self).action_confirm()
        try:
            for order in self:
                for line in order.order_line:
                    #_logger.info(line)
                    #_logger.info(line.is_delivery)
                    #_logger.info(line.price_unit)
                    if line.is_delivery and line.price_unit<=0.0:
                        #_logger.info(line)
                        line.write({ "qty_to_invoice": 0.0 })
                        #_logger.info(line.qty_to_invoice)
        except:
            pass;

        try:
            company = self.env.user.company_id
            _logger.info("Company: "+str(company))
            _logger.info("Order done: company.mercadolibre_cron_post_update_stock: "+str(company.mercadolibre_cron_post_update_stock))
            for order in self:
                for line in order.order_line:
                    if (company.mercadolibre_cron_post_update_stock):
                        if line.product_id and line.product_id.meli_id and line.product_id.meli_pub:
                            _logger.info("Order done: product_post_stock: "+str(line.product_id.meli_id))
                            line.product_id.product_post_stock()
        except:
            pass;
        return res

    def action_done(self):
        _logger.info("meli order action done: " + str(self.mapped("name")) )
        res = super(sale_order,self).action_done()
        try:
            for order in self:
                for line in order.order_line:
                    #_logger.info(line)
                    #_logger.info(line.is_delivery)
                    #_logger.info(line.price_unit)
                    if line.is_delivery and line.price_unit<=0.0:
                        #_logger.info(line)
                        line.write({ "qty_to_invoice": 0.0 })
                        #_logger.info(line.qty_to_invoice)
        except:
            pass;

        try:
            company = self.env.user.company_id
            _logger.info("Company: "+str(company))
            _logger.info("Order done: company.mercadolibre_cron_post_update_stock: "+str(company.mercadolibre_cron_post_update_stock))
            for order in self:
                for line in order.order_line:
                    if (company.mercadolibre_cron_post_update_stock):
                        if line.product_id and line.product_id.meli_id and line.product_id.meli_pub:
                            _logger.info("Order done: product_post_stock: "+str(line.product_id.meli_id))
                            line.product_id.product_post_stock()
        except:
            pass;
        return res

    def _get_meli_invoices(self):
        invoices = self.env[acc_inv_model].search([('origin','=',self.name)])
        #_logger.info("_get_meli_invoices")
        #_logger.info(self)
        #_logger.info(invoices)
        if invoices:
            return invoices[0]
        return None

    def confirm_ml( self, meli=None, config=None ):
        try:
            _logger.info("meli_oerp confirm_ml")
            company = (config and 'company_id' in config._fields and config.company_id) or self.env.user.company_id
            config = config or company

            stock_picking = self.env["stock.picking"]

            if (self.meli_status=="cancelled"):
                self.action_cancel()

            if (config.mercadolibre_order_confirmation=="paid_confirm"):

                if ( (self.state=="draft" or self.state=="sent") and self.meli_status=="paid"):
                    _logger.info("paid_confirm ok! confirming sale")
                    self.action_confirm()

            if (config.mercadolibre_order_confirmation=="paid_delivered"):

                if ( (self.state=="draft" or self.state=="sent") and self.meli_status=="paid"):
                    _logger.info("paid_delivered ok! confirming sale")
                    self.action_confirm()

                if (self.state=="sale" or self.state=="done"):
                    #spick = stock_picking.search([('order_id','=',self.id)])
                    _logger.info("paid_delivered ok! delivering")
                    for spick in self.picking_ids:
                        _logger.info(spick)
                        if (spick.move_line_ids):
                            _logger.info(spick.move_line_ids)
                            if (len(spick.move_line_ids)>=1):
                                for pop in spick.move_line_ids:
                                    _logger.info(pop)
                                    if (pop.qty_done==0.0 and pop.product_qty>=0.0):
                                        pop.qty_done = pop.product_qty
                                _logger.info("do_new_transfer")
                                spick.action_done()


            if (config.mercadolibre_order_confirmation=="paid_confirm_with_invoice"):
                if ( (self.state=="draft" or self.state=="sent") and self.meli_status=="paid"):
                    _logger.info("paid_confirm with invoice ok! confirming sale and create invoice")
                    self.action_confirm()
                    self.action_invoice_create()
        except Exception as e:
            _logger.info("Confirm Order Exception")
            _logger.error(e, exc_info=True)
            pass

    _sql_constraints = [
        ('unique_meli_order_id', 'unique(meli_order_id)', 'Mei Order id already exists!')
    ]
sale_order()

class mercadolibre_orders(models.Model):
    _name = "mercadolibre.orders"
    _description = "Pedidos en MercadoLibre"

    _inherit = ['portal.mixin', 'mail.thread', 'mail.activity.mixin']

    def street(self, Receiver ):
        full_street = 'no street'
        if (Receiver and 'address_line' in Receiver):
            full_street = Receiver['address_line']
        return full_street

    def city(self, Receiver ):
        full_city = ''
        if (Receiver and 'city' in Receiver):
            full_city = Receiver['city']['name']
        return full_city

    def state(self, country_id, Receiver ):
        full_state = ''
        state_id = False
        if (Receiver and 'state' in Receiver):
            if ('id' in Receiver['state']):
                state = self.env['res.country.state'].search([('code','like',Receiver['state']['id']),('country_id','=',country_id)])
                if (len(state)):
                    state_id = state[0].id
                    return state_id
            id_ml = 'id' in Receiver['state'] and Receiver['state']['id'].split("-")
            #_logger.info(Receiver)
            #_logger.info(id_ml)
            if (id_ml and len(id_ml)==2):
                id = id_ml[1]
                state = self.env['res.country.state'].search([('code','like',id),('country_id','=',country_id)])
                if (len(state)):
                    state_id = state[0].id
                    return state_id
            if ('name' in Receiver['state']):
                full_state = Receiver['state']['name']
                state = self.env['res.country.state'].search(['&',('name','like',full_state),('country_id','=',country_id)])
                if (len(state)):
                    state_id = state[0].id
        return state_id

    def country(self, Receiver ):
        full_country = ''
        country_id = False
        if (Receiver and 'country' in Receiver):
            if ('id' in Receiver['country']):
                country = self.env['res.country'].search([('code','like',Receiver['country']['id'])])
                if (len(country)):
                    country_id = country[0].id
                    return country_id
            if ('name' in Receiver['country']):
                full_country = Receiver['country']['name']
                country = self.env['res.country'].search([('name','like',full_country)])
                if (len(country)):
                    country_id = country.id
        return country_id

    def billing_info( self, billing_json, context=None ):
        billinginfo = ''

        if 'doc_type' in billing_json:
            if billing_json['doc_type']:
                billinginfo+= billing_json['doc_type']

        if 'doc_number' in billing_json:
            if billing_json['doc_number']:
                billinginfo+= billing_json['doc_number']

        return billinginfo

    def full_phone( self, buyer_json, context=None ):
        full_phone = ''
        if "phone" in buyer_json:
            phone_json = buyer_json["phone"]
            if 'area_code' in phone_json:
                if phone_json['area_code']:
                    full_phone+= phone_json['area_code']

            if 'number' in phone_json:
                if phone_json['number']:
                    full_phone+= phone_json['number']

            if 'extension' in phone_json:
                if phone_json['extension']:
                    full_phone+= phone_json['extension']

        return full_phone

    def full_alt_phone( self, buyer_json, context=None ):
        full_phone = ''
        if "alternative_phone" in buyer_json:
            phone_json = buyer_json["alternative_phone"]
            if 'area_code' in phone_json:
                if phone_json['area_code']:
                    full_phone+= phone_json['area_code']

            if 'number' in phone_json:
                if phone_json['number']:
                    full_phone+= phone_json['number']

            if 'extension' in phone_json:
                if phone_json['extension']:
                    full_phone+= phone_json['extension']

        return full_phone

    def _set_product_unit_price( self, product_related_obj, Item ):
        product_template = product_related_obj.product_tmpl_id
        ml_price_converted = float(Item['unit_price'])
        #11.0
        #tax_excluded = self.env.user.has_group('sale.group_show_price_subtotal')
        #12.0 and 13.0
        tax_excluded = ml_tax_excluded(self)
        if ( tax_excluded and product_template.taxes_id ):
            txfixed = 0
            txpercent = 0
            #_logger.info("Adjust taxes")
            for txid in product_template.taxes_id:
                if (txid.type_tax_use=="sale" and not txid.price_include):
                    if (txid.amount_type=="percent"):
                        txpercent = txpercent + txid.amount
                    if (txid.amount_type=="fixed"):
                        txfixed = txfixed + txid.amount
                    #_logger.info(txid.amount)
            if (txfixed>0 or txpercent>0):
                #_logger.info("Tx Total:"+str(txtotal)+" to Price:"+str(ml_price_converted))
                ml_price_converted = txfixed + ml_price_converted / (1.0 + txpercent*0.01)
                _logger.info("Price adjusted with taxes:"+str(ml_price_converted))

        ml_price_converted = round(ml_price_converted,2)

        upd_line = {
            "price_unit": ml_price_converted,
        }
        #else:
        #    if ( float(Item['unit_price']) == product_template.lst_price and not self.env.user.has_group('sale.group_show_price_subtotal')):
        #        upd_line["tax_id"] = None
        return upd_line

    def pretty_json( self, ids, data, indent=0, context=None ):
        return json.dumps( data, sort_keys=False, indent=4 )

    def prepare_ml_order_vals( self, meli=None, order_json=None, config=None ):

        company = self.env.user.company_id

        if not config:
            config = company

        seller_id = None
        if config.mercadolibre_seller_user:
            seller_id = config.mercadolibre_seller_user.id

        order_fields = {
            'name': "MO [%s]" % ( str(order_json["id"]) ),
            'company_id': company.id,
            'seller_id': seller_id,
            'order_id': '%s' % (str(order_json["id"])),
            'status': order_json["status"],
            'status_detail': order_json["status_detail"] or '' ,
            'fee_amount': 0.0,
            'total_amount': order_json["total_amount"],
            'paid_amount': order_json["paid_amount"],
            'currency_id': order_json["currency_id"],
            'date_created': ml_datetime(order_json["date_created"]),
            'date_closed': ml_datetime(order_json["date_closed"]),
            'pack_order': False,
            'catalog_order': False,
            'seller': ("seller" in order_json and str(order_json["seller"])) or ''
        }
        if "pack_id" in order_json and order_json["pack_id"]:
            order_fields['pack_id'] = order_json["pack_id"]
        if 'tags' in order_json:
            order_fields["tags"] = order_json["tags"]
            if 'pack_order' in order_json["tags"]:
                order_fields["pack_order"] = True
            if 'catalog' in order_json["tags"]:
                order_fields["catalog_order"] = True
                #debemos buscar el codigo relacionado pero al producto real del catalogo: que se encuentra.
        return order_fields

    def prepare_sale_order_vals( self, meli=None, rjson=None ):
        vals = {}
        return vals

    def search_sale_order( self, order_id, meli=None, rjson=None ):
        sorder = None

        return sorder

    def search_ml_order( self, order_id, meli=None, rjson=None ):
        mlorder = None

        return mlorder

    def search_meli_product( self, meli=None, meli_item=None, config=None ):
        product_obj = self.env['product.product']
        if not meli_item:
            return None
        meli_id = meli_item['id']
        meli_id_variation = ("variation_id" in meli_item and meli_item['variation_id'])
        if (meli_id_variation):
            product_related = product_obj.search([ ('meli_id','=',meli_id), ('meli_id_variation','=',meli_id_variation) ])
        else:
            product_related = product_obj.search([('meli_id','=', meli_id)])
        return product_related


    def orders_update_order_json( self, data, context=None, config=None, meli=None ):

        _logger.info("orders_update_order_json > data "+str(data['id']) + " json:" + str(data['order_json']['id']) )

        oid = data["id"]
        order_json = data["order_json"]
        #_logger.info( "data:" + str(data) )
        company = self.env.user.company_id
        if not config:
            config = company
        if not meli:
            meli = self.env['meli.util'].get_new_instance(company)

        saleorder_obj = self.env['sale.order']
        saleorderline_obj = self.env['sale.order.line']
        product_obj = self.env['product.product']

        pricelist_obj = self.env['product.pricelist']
        respartner_obj = self.env['res.partner']

        plistid = None
        if config.mercadolibre_pricelist:
            plistid = config.mercadolibre_pricelist
        else:
            plistids = pricelist_obj.search([])[0]
            if plistids:
                plistid = plistids

        order_obj = self.env['mercadolibre.orders']
        buyers_obj = self.env['mercadolibre.buyers']
        posting_obj = self.env['mercadolibre.posting']
        order_items_obj = self.env['mercadolibre.order_items']
        payments_obj = self.env['mercadolibre.payments']
        shipment_obj = self.env['mercadolibre.shipment']

        order = None
        sorder = None

        # if id is defined, we are updating existing one
        if (oid):
            order = order_obj.browse(oid )
            if (order):
                _logger.info(order)
                sorder_s = saleorder_obj.search([ ('meli_order_id','=',order.order_id) ] )
                if (sorder_s):
                    _logger.info(sorder_s)
                    if (len(sorder_s)>1):
                        sorder = sorder_s[0]
                    else:
                        sorder = sorder_s
        else:
        #we search for existing order with same order_id => "id"
            order_s = order_obj.search([ ('order_id','=','%s' % (str(order_json["id"]))) ] )
            if (order_s):
                if (len(order_s)>1):
                    order = order_s[0]
                else:
                    order = order_s
            #    order = order_obj.browse(order_s[0] )

            sorder_s = saleorder_obj.search([ ('meli_order_id','=','%s' % (str(order_json["id"]))) ] )
            if (sorder_s):
                if (len(sorder_s)>1):
                    sorder = sorder_s[0]
                else:
                    sorder = sorder_s
            #if (sorder_s and len(sorder_s)>0):
            #    sorder = saleorder_obj.browse(sorder_s[0] )
        seller_id = None
        if config.mercadolibre_seller_user:
            seller_id = config.mercadolibre_seller_user.id

        order_fields = self.prepare_ml_order_vals( order_json=order_json, meli=meli, config=config )

        partner_id = False
        partner_shipping_id = False

        if 'buyer' in order_json:
            Buyer = order_json['buyer']
            Receiver = False
            if ('shipping' in order_json):
                if ('receiver_address' in order_json['shipping']):
                    Receiver = order_json['shipping']['receiver_address']
                elif ('id' in order_json['shipping']):
                    Shipment = self.env["mercadolibre.shipment"].search([('shipping_id','=',order_json['shipping']["id"])])
                    if (len(Shipment)==1):
                        Receiver = {
                            'receiver_address': Shipment.receiver_address_line,
                            'country': {
                                'id': Shipment.receiver_country_code,
                                'name': Shipment.receiver_country
                            },
                            'state': {
                                'name': Shipment.receiver_state,
                                'id': Shipment.receiver_state_code
                            },
                            'city': {
                                'name': Shipment.receiver_city,
                                'id': Shipment.receiver_city_code
                            }
                        }


            meli_buyer_fields = {
                'name': Buyer['first_name']+' '+Buyer['last_name'],
                'street': self.street(Receiver),
                'city': self.city(Receiver),
                'country_id': self.country(Receiver),
                'state_id': self.state(self.country(Receiver),Receiver),
                'phone': self.full_phone( Buyer ),
                #'email': Buyer['email'],
                'meli_buyer_id': Buyer['id']
            }

            if "l10n_co_cities.city" in self.env:
                state_id = meli_buyer_fields["state_id"]
                city = self.env["l10n_co_cities.city"].search([('city_name','like',meli_buyer_fields["city"])])

                if not city and state_id:
                    _logger.warning("City not found: " + str(state_id))
                    _logger.info("Search first city for state: " + str(state_id))
                    city = self.env["l10n_co_cities.city"].search([('state_id','=',state_id)])

                if city:
                    _logger.info(city)
                    city = city[0]

                    _logger.info("Founded cities for state: " + str(state_id)+ " city_name: "+str(city.city_name))

                    meli_buyer_fields["cities"] = city.id

                    postal = self.env["l10n_co_postal.postal_code"].search([('city_id','=',city.id)])
                    if postal:
                        postal = postal[0]
                        meli_buyer_fields["postal_id"] = postal.id
                    else:
                        _logger.error("Postal code not found for: " + str(city.city_name)+ "["+str(city.id)+"]")
                else:
                    _logger.error("City not found for: " + str(meli_buyer_fields["city"]))


            buyer_fields = {
                'name': Buyer['first_name']+' '+Buyer['last_name'],
                'buyer_id': Buyer['id'],
                'nickname': Buyer['nickname'],
                'email': Buyer['email'],
                'phone': self.full_phone( Buyer ),
                'alternative_phone': self.full_alt_phone( Buyer ),
                'first_name': Buyer['first_name'],
                'last_name': Buyer['last_name'],
                'billing_info': self.billing_info(Buyer['billing_info']),
            }
            if ('doc_type' in Buyer['billing_info']):
                buyer_fields['billing_info_doc_type'] = Buyer['billing_info']['doc_type']
                if ('doc_number' in Buyer['billing_info']):
                    buyer_fields['billing_info_doc_number'] = Buyer['billing_info']['doc_number']
            else:
                buyer_fields['billing_info_doc_type'] = ''
                buyer_fields['billing_info_doc_number'] = ''


            buyer_ids = buyers_obj.search([  ('buyer_id','=',buyer_fields['buyer_id'] ) ] )
            buyer_id = 0
            if (buyer_ids==False or len(buyer_ids)==0):
                _logger.info( "creating buyer")
                _logger.info(buyer_fields)
                buyer_id = buyers_obj.create(( buyer_fields ))
            else:
                buyer_id = buyer_ids
                buyer_id.write( ( buyer_fields ) )
                #if (len(buyer_ids)>0):
                #      buyer_id = buyer_ids[0]
            if (buyer_id):
                meli_buyer_fields['meli_buyer'] = buyer_id.id
                if (('doc_type' in Buyer['billing_info']) and ('afip.responsability.type' in self.env)):
                    doctypeid = self.env['res.partner.id_category'].search([('code','=',Buyer['billing_info']['doc_type'])]).id
                    if (doctypeid):
                        meli_buyer_fields['main_id_category_id'] = doctypeid
                        meli_buyer_fields['main_id_number'] = Buyer['billing_info']['doc_number']
                        if (Buyer['billing_info']['doc_type']=="CUIT"):
                            #IVA Responsable Inscripto
                            afipid = self.env['afip.responsability.type'].search([('code','=',1)]).id
                            meli_buyer_fields["afip_responsability_type_id"] = afipid
                        else:
                            #if (Buyer['billing_info']['doc_type']=="DNI"):
                            #Consumidor Final
                            afipid = self.env['afip.responsability.type'].search([('code','=',5)]).id
                            meli_buyer_fields["afip_responsability_type_id"] = afipid
                    else:
                        _logger.error("res.partner.id_category:" + str(Buyer['billing_info']['doc_type']))


                #Chile
                if ( ('doc_type' in Buyer['billing_info']) and ('l10n_latam_identification_type_id' in self.env['res.partner']._fields) ):
                    if (Buyer['billing_info']['doc_type']=="RUT"):
                        meli_buyer_fields['l10n_latam_identification_type_id'] = 4
                    if (Buyer['billing_info']['doc_type']=="RUN"):
                        meli_buyer_fields['l10n_latam_identification_type_id'] = 5

                    meli_buyer_fields['vat'] = Buyer['billing_info']['doc_number']


                #Colombia
                if ( ('doc_type' in Buyer['billing_info']) and ('l10n_co_document_type' in self.env['res.partner']._fields) ):
                    if ("fe_es_compania" in self.env['res.partner']._fields ):
                        meli_buyer_fields['fe_es_compania'] = '2'
                    if ("fe_correo_electronico" in self.env['res.partner']._fields ):
                        meli_buyer_fields['fe_correo_electronico'] = Buyer['email']

                    if (Buyer['billing_info']['doc_type']=="CC" or Buyer['billing_info']['doc_type']=="C.C."):
                        meli_buyer_fields['l10n_co_document_type'] = 'national_citizen_id'
                        if ("fe_tipo_documento" in self.env['res.partner']._fields):
                            meli_buyer_fields['fe_tipo_documento'] = '13'
                        if ("fe_tipo_regimen" in self.env['res.partner']._fields ):
                            meli_buyer_fields['fe_tipo_regimen'] = '00'
                        if ("fe_regimen_fiscal" in self.env['res.partner']._fields ):
                            meli_buyer_fields['fe_regimen_fiscal'] = '49'
                        if ("responsabilidad_fiscal_fe" in self.env['res.partner']._fields ):
                            meli_buyer_fields['responsabilidad_fiscal_fe'] = [ ( 6, 0, [29] ) ]

                    if (Buyer['billing_info']['doc_type']=="NIT"):
                        meli_buyer_fields['l10n_co_document_type'] = 'rut'
                        if ("fe_tipo_documento" in self.env['res.partner']._fields):
                            meli_buyer_fields['fe_tipo_documento'] = '31'
                        if ("fe_es_compania" in self.env['res.partner']._fields ):
                            meli_buyer_fields['fe_es_compania'] = '1'
                        #if ("fe_tipo_regimen" in self.env['res.partner']._fields ):
                        #    meli_buyer_fields['fe_tipo_regimen'] = '04'
                        #if ("fe_regimen_fiscal" in self.env['res.partner']._fields ):
                        #    meli_buyer_fields['fe_regimen_fiscal'] = '48'

                    if (Buyer['billing_info']['doc_type']=="CE"):
                        meli_buyer_fields['l10n_co_document_type'] = 'foreign_id_card'
                        if ("fe_tipo_documento" in self.env['res.partner']._fields):
                            meli_buyer_fields['fe_tipo_documento'] = '22'
                        if ("fe_tipo_regimen" in self.env['res.partner']._fields ):
                            meli_buyer_fields['fe_tipo_regimen'] = '00'
                        if ("fe_regimen_fiscal" in self.env['res.partner']._fields ):
                            meli_buyer_fields['fe_regimen_fiscal'] = '49'
                        if ("responsabilidad_fiscal_fe" in self.env['res.partner']._fields ):
                            meli_buyer_fields['responsabilidad_fiscal_fe'] = [ ( 6, 0, [29] ) ]

                    meli_buyer_fields['vat'] = Buyer['billing_info']['doc_number']
                    if ("fe_nit" in self.env['res.partner']._fields):
                        meli_buyer_fields['fe_nit'] = Buyer['billing_info']['doc_number']
                        if (Buyer['billing_info']['doc_type']=="NIT"):
                            meli_buyer_fields['fe_nit'] = Buyer['billing_info']['doc_number'][0:10]
                            if ("fe_digito_verificacion" in self.env['res.partner']._fields):
                                meli_buyer_fields['fe_digito_verificacion'] = Buyer['billing_info']['doc_number'][-1]

                    if ("fe_primer_nombre" in self.env['res.partner']._fields):
                        nn = Buyer['first_name'].split(" ")
                        if (len(nn)>1):
                            meli_buyer_fields['fe_primer_nombre'] = nn[0]
                            meli_buyer_fields['fe_segundo_nombre'] = nn[1]
                        else:
                            meli_buyer_fields['fe_primer_nombre'] = Buyer['first_name']
                    if ("fe_primer_apellido" in self.env['res.partner']._fields):
                        nn = Buyer['last_name'].split(" ")
                        if (len(nn)>1):
                            meli_buyer_fields['fe_primer_apellido'] = nn[0]
                            meli_buyer_fields['fe_segundo_apellido'] = nn[1]
                        else:
                            meli_buyer_fields['fe_primer_apellido'] = Buyer['last_name']


            partner_ids = respartner_obj.search([  ('meli_buyer_id','=',buyer_fields['buyer_id'] ) ] )
            if (len(partner_ids)>0):
                partner_id = partner_ids[0]
            if ("fe_regimen_fiscal" in self.env['res.partner']._fields):
                if (partner_id and not partner_id.fe_regimen_fiscal):
                    meli_buyer_fields['fe_regimen_fiscal'] = '49';
                else:
                    meli_buyer_fields['fe_regimen_fiscal'] = '49';
            if not partner_id:
                #_logger.info( "creating partner:" + str(meli_buyer_fields) )
                partner_id = respartner_obj.create(( meli_buyer_fields ))
            else:
                partner_id = partner_ids[0]
                _logger.info("Updating partner (do not update principal, always create new one)")
                _logger.info(meli_buyer_fields)
                #complete country at most:
                partner_update = {}
                if not partner_id.country_id:
                    partner_update.update({'country_id': self.country(Receiver)})
                if not partner_id.state_id:
                    partner_update.update({ 'state_id': self.state(self.country(Receiver), Receiver)})
                if partner_update:
                    partner_id.write(partner_update)


                if (partner_id.email and (partner_id.email==buyer_fields["email"] or "mercadolibre.com" in partner_id.email)):
                    #eliminar email de ML que no es valido
                    meli_buyer_fields["email"] = ''
                #crear nueva direccion de entrega
                #partner_id.write( meli_buyer_fields )

            if (partner_id and 1==2):
                pdelivery_fields = {
                    "type": "delivery",
                    "parent_id": partner_id.id,
                    'name': meli_buyer_fields['name'],
                    'street': meli_buyer_fields['street'],
                    #'street2': meli_buyer_fields['name'],
                    'city': meli_buyer_fields['city'],
                    'country_id': meli_buyer_fields['country_id'],
                    'state_id': meli_buyer_fields['state_id'],
                    #'zip': meli_buyer_fields['name'],
                    #"comment": ("location_addressNotes" in contactfields and contactfields["location_addressNotes"]) or ""
                    #'producteca_bindings': [(6, 0, [client.id])]
                    #'phone': self.full_phone( contactfields,billing=True ),
                    #'email':contactfields['billingInfo_email'],
                    #'producteca_bindings': [(6, 0, [client.id])]
                }<commit_msg>Updating country id and state id<commit_after># -*- coding: utf-8 -*-
##############################################################################
#
#    OpenERP, Open Source Management Solution
#    Copyright (C) 2004-2009 Tiny SPRL (<http://tiny.be>).
#
#    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 <http://www.gnu.org/licenses/>.
#
##############################################################################

from odoo import fields, osv, models, api
import logging
from .meli_oerp_config import *

from ..melisdk.meli import Meli

import json

import logging
_logger = logging.getLogger(__name__)

from . import posting
from . import product
from . import shipment
from dateutil.parser import *
from datetime import *
from urllib.request import urlopen
import requests
try:
    from urllib import urlencode
except ImportError:
    from urllib.parse import urlencode

from . import versions
from .versions import *

class sale_order_line(models.Model):
    _inherit = "sale.order.line"

    meli_order_item_id = fields.Char('Meli Order Item Id')
    meli_order_item_variation_id = fields.Char('Meli Order Item Variation Id')

sale_order_line()

class sale_order(models.Model):
    _inherit = "sale.order"

    meli_order_id =  fields.Char(string='Meli Order Id',index=True)
    meli_orders = fields.Many2many('mercadolibre.orders',string="ML Orders")
    meli_status = fields.Selection( [
        #Initial state of an order, and it has no payment yet.
                                        ("confirmed","Confirmado"),
        #The order needs a payment to become confirmed and show users information.
                                      ("payment_required","Pago requerido"),
        #There is a payment related with the order, but it has not accredited yet
                                    ("payment_in_process","Pago en proceso"),
        #The order has a related payment and it has been accredited.
                                    ("paid","Pagado"),
        #The order has a related partial payment and it has been accredited.
                                    ("partially_paid","Parcialmente Pagado"),
        #The order has not completed by some reason.
                                    ("cancelled","Cancelado")], string='Order Status');

    meli_status_detail = fields.Text(string='Status detail, in case the order was cancelled.')
    meli_date_created = fields.Datetime('Creation date')
    meli_date_closed = fields.Datetime('Closing date')

#        'meli_order_items': fields.one2many('mercadolibre.order_items','order_id','Order Items' ),
#        'meli_payments': fields.one2many('mercadolibre.payments','order_id','Payments' ),
    meli_shipping = fields.Text(string="Shipping")

    meli_total_amount = fields.Float(string='Total amount')
    meli_shipping_cost = fields.Float(string='Shipping Cost',help='Gastos de envío')
    meli_shipping_list_cost = fields.Float(string='Shipping List Cost',help='Gastos de envío, costo de lista/interno')
    meli_paid_amount = fields.Float(string='Paid amount',help='Paid amount (include shipping cost)')
    meli_fee_amount = fields.Float(string='Fee amount',help="Comisión")
    meli_currency_id = fields.Char(string='Currency ML')
#        'buyer': fields.many2one( "mercadolibre.buyers","Buyer"),
#       'meli_seller': fields.text( string='Seller' ),
    meli_shipping_id =  fields.Char('Meli Shipping Id')
    meli_shipment = fields.Many2one('mercadolibre.shipment',string='Meli Shipment Obj')
    meli_shipment_logistic_type = fields.Char(string="Logistic Type",index=True)

    def action_confirm(self):
        _logger.info("meli order action_confirm: " + str(self.mapped("name")) )
        res = super(sale_order,self).action_confirm()
        try:
            for order in self:
                for line in order.order_line:
                    #_logger.info(line)
                    #_logger.info(line.is_delivery)
                    #_logger.info(line.price_unit)
                    if line.is_delivery and line.price_unit<=0.0:
                        #_logger.info(line)
                        line.write({ "qty_to_invoice": 0.0 })
                        #_logger.info(line.qty_to_invoice)
        except:
            pass;

        try:
            company = self.env.user.company_id
            _logger.info("Company: "+str(company))
            _logger.info("Order done: company.mercadolibre_cron_post_update_stock: "+str(company.mercadolibre_cron_post_update_stock))
            for order in self:
                for line in order.order_line:
                    if (company.mercadolibre_cron_post_update_stock):
                        if line.product_id and line.product_id.meli_id and line.product_id.meli_pub:
                            _logger.info("Order done: product_post_stock: "+str(line.product_id.meli_id))
                            line.product_id.product_post_stock()
        except:
            pass;
        return res

    def action_done(self):
        _logger.info("meli order action done: " + str(self.mapped("name")) )
        res = super(sale_order,self).action_done()
        try:
            for order in self:
                for line in order.order_line:
                    #_logger.info(line)
                    #_logger.info(line.is_delivery)
                    #_logger.info(line.price_unit)
                    if line.is_delivery and line.price_unit<=0.0:
                        #_logger.info(line)
                        line.write({ "qty_to_invoice": 0.0 })
                        #_logger.info(line.qty_to_invoice)
        except:
            pass;

        try:
            company = self.env.user.company_id
            _logger.info("Company: "+str(company))
            _logger.info("Order done: company.mercadolibre_cron_post_update_stock: "+str(company.mercadolibre_cron_post_update_stock))
            for order in self:
                for line in order.order_line:
                    if (company.mercadolibre_cron_post_update_stock):
                        if line.product_id and line.product_id.meli_id and line.product_id.meli_pub:
                            _logger.info("Order done: product_post_stock: "+str(line.product_id.meli_id))
                            line.product_id.product_post_stock()
        except:
            pass;
        return res

    def _get_meli_invoices(self):
        invoices = self.env[acc_inv_model].search([('origin','=',self.name)])
        #_logger.info("_get_meli_invoices")
        #_logger.info(self)
        #_logger.info(invoices)
        if invoices:
            return invoices[0]
        return None

    def confirm_ml( self, meli=None, config=None ):
        try:
            _logger.info("meli_oerp confirm_ml")
            company = (config and 'company_id' in config._fields and config.company_id) or self.env.user.company_id
            config = config or company

            stock_picking = self.env["stock.picking"]

            if (self.meli_status=="cancelled"):
                self.action_cancel()

            if (config.mercadolibre_order_confirmation=="paid_confirm"):

                if ( (self.state=="draft" or self.state=="sent") and self.meli_status=="paid"):
                    _logger.info("paid_confirm ok! confirming sale")
                    self.action_confirm()

            if (config.mercadolibre_order_confirmation=="paid_delivered"):

                if ( (self.state=="draft" or self.state=="sent") and self.meli_status=="paid"):
                    _logger.info("paid_delivered ok! confirming sale")
                    self.action_confirm()

                if (self.state=="sale" or self.state=="done"):
                    #spick = stock_picking.search([('order_id','=',self.id)])
                    _logger.info("paid_delivered ok! delivering")
                    for spick in self.picking_ids:
                        _logger.info(spick)
                        if (spick.move_line_ids):
                            _logger.info(spick.move_line_ids)
                            if (len(spick.move_line_ids)>=1):
                                for pop in spick.move_line_ids:
                                    _logger.info(pop)
                                    if (pop.qty_done==0.0 and pop.product_qty>=0.0):
                                        pop.qty_done = pop.product_qty
                                _logger.info("do_new_transfer")
                                spick.action_done()


            if (config.mercadolibre_order_confirmation=="paid_confirm_with_invoice"):
                if ( (self.state=="draft" or self.state=="sent") and self.meli_status=="paid"):
                    _logger.info("paid_confirm with invoice ok! confirming sale and create invoice")
                    self.action_confirm()
                    self.action_invoice_create()
        except Exception as e:
            _logger.info("Confirm Order Exception")
            _logger.error(e, exc_info=True)
            pass

    _sql_constraints = [
        ('unique_meli_order_id', 'unique(meli_order_id)', 'Mei Order id already exists!')
    ]
sale_order()

class mercadolibre_orders(models.Model):
    _name = "mercadolibre.orders"
    _description = "Pedidos en MercadoLibre"

    _inherit = ['portal.mixin', 'mail.thread', 'mail.activity.mixin']

    def street(self, Receiver ):
        full_street = 'no street'
        if (Receiver and 'address_line' in Receiver):
            full_street = Receiver['address_line']
        return full_street

    def city(self, Receiver ):
        full_city = ''
        if (Receiver and 'city' in Receiver):
            full_city = Receiver['city']['name']
        return full_city

    def state(self, country_id, Receiver ):
        full_state = ''
        state_id = False
        if (Receiver and 'state' in Receiver):
            if ('id' in Receiver['state']):
                state = self.env['res.country.state'].search([('code','like',Receiver['state']['id']),('country_id','=',country_id)])
                if (len(state)):
                    state_id = state[0].id
                    return state_id
            id_ml = 'id' in Receiver['state'] and Receiver['state']['id'].split("-")
            #_logger.info(Receiver)
            #_logger.info(id_ml)
            if (id_ml and len(id_ml)==2):
                id = id_ml[1]
                state = self.env['res.country.state'].search([('code','like',id),('country_id','=',country_id)])
                if (len(state)):
                    state_id = state[0].id
                    return state_id
            if ('name' in Receiver['state']):
                full_state = Receiver['state']['name']
                state = self.env['res.country.state'].search(['&',('name','like',full_state),('country_id','=',country_id)])
                if (len(state)):
                    state_id = state[0].id
        return state_id

    def country(self, Receiver ):
        full_country = ''
        country_id = False
        if (Receiver and 'country' in Receiver):
            if ('id' in Receiver['country']):
                country = self.env['res.country'].search([('code','like',Receiver['country']['id'])])
                if (len(country)):
                    country_id = country[0].id
                    return country_id
            if ('name' in Receiver['country']):
                full_country = Receiver['country']['name']
                country = self.env['res.country'].search([('name','like',full_country)])
                if (len(country)):
                    country_id = country.id
        return country_id

    def billing_info( self, billing_json, context=None ):
        billinginfo = ''

        if 'doc_type' in billing_json:
            if billing_json['doc_type']:
                billinginfo+= billing_json['doc_type']

        if 'doc_number' in billing_json:
            if billing_json['doc_number']:
                billinginfo+= billing_json['doc_number']

        return billinginfo

    def full_phone( self, buyer_json, context=None ):
        full_phone = ''
        if "phone" in buyer_json:
            phone_json = buyer_json["phone"]
            if 'area_code' in phone_json:
                if phone_json['area_code']:
                    full_phone+= phone_json['area_code']

            if 'number' in phone_json:
                if phone_json['number']:
                    full_phone+= phone_json['number']

            if 'extension' in phone_json:
                if phone_json['extension']:
                    full_phone+= phone_json['extension']

        return full_phone

    def full_alt_phone( self, buyer_json, context=None ):
        full_phone = ''
        if "alternative_phone" in buyer_json:
            phone_json = buyer_json["alternative_phone"]
            if 'area_code' in phone_json:
                if phone_json['area_code']:
                    full_phone+= phone_json['area_code']

            if 'number' in phone_json:
                if phone_json['number']:
                    full_phone+= phone_json['number']

            if 'extension' in phone_json:
                if phone_json['extension']:
                    full_phone+= phone_json['extension']

        return full_phone

    def _set_product_unit_price( self, product_related_obj, Item ):
        product_template = product_related_obj.product_tmpl_id
        ml_price_converted = float(Item['unit_price'])
        #11.0
        #tax_excluded = self.env.user.has_group('sale.group_show_price_subtotal')
        #12.0 and 13.0
        tax_excluded = ml_tax_excluded(self)
        if ( tax_excluded and product_template.taxes_id ):
            txfixed = 0
            txpercent = 0
            #_logger.info("Adjust taxes")
            for txid in product_template.taxes_id:
                if (txid.type_tax_use=="sale" and not txid.price_include):
                    if (txid.amount_type=="percent"):
                        txpercent = txpercent + txid.amount
                    if (txid.amount_type=="fixed"):
                        txfixed = txfixed + txid.amount
                    #_logger.info(txid.amount)
            if (txfixed>0 or txpercent>0):
                #_logger.info("Tx Total:"+str(txtotal)+" to Price:"+str(ml_price_converted))
                ml_price_converted = txfixed + ml_price_converted / (1.0 + txpercent*0.01)
                _logger.info("Price adjusted with taxes:"+str(ml_price_converted))

        ml_price_converted = round(ml_price_converted,2)

        upd_line = {
            "price_unit": ml_price_converted,
        }
        #else:
        #    if ( float(Item['unit_price']) == product_template.lst_price and not self.env.user.has_group('sale.group_show_price_subtotal')):
        #        upd_line["tax_id"] = None
        return upd_line

    def pretty_json( self, ids, data, indent=0, context=None ):
        return json.dumps( data, sort_keys=False, indent=4 )

    def prepare_ml_order_vals( self, meli=None, order_json=None, config=None ):

        company = self.env.user.company_id

        if not config:
            config = company

        seller_id = None
        if config.mercadolibre_seller_user:
            seller_id = config.mercadolibre_seller_user.id

        order_fields = {
            'name': "MO [%s]" % ( str(order_json["id"]) ),
            'company_id': company.id,
            'seller_id': seller_id,
            'order_id': '%s' % (str(order_json["id"])),
            'status': order_json["status"],
            'status_detail': order_json["status_detail"] or '' ,
            'fee_amount': 0.0,
            'total_amount': order_json["total_amount"],
            'paid_amount': order_json["paid_amount"],
            'currency_id': order_json["currency_id"],
            'date_created': ml_datetime(order_json["date_created"]),
            'date_closed': ml_datetime(order_json["date_closed"]),
            'pack_order': False,
            'catalog_order': False,
            'seller': ("seller" in order_json and str(order_json["seller"])) or ''
        }
        if "pack_id" in order_json and order_json["pack_id"]:
            order_fields['pack_id'] = order_json["pack_id"]
        if 'tags' in order_json:
            order_fields["tags"] = order_json["tags"]
            if 'pack_order' in order_json["tags"]:
                order_fields["pack_order"] = True
            if 'catalog' in order_json["tags"]:
                order_fields["catalog_order"] = True
                #debemos buscar el codigo relacionado pero al producto real del catalogo: que se encuentra.
        return order_fields

    def prepare_sale_order_vals( self, meli=None, rjson=None ):
        vals = {}
        return vals

    def search_sale_order( self, order_id, meli=None, rjson=None ):
        sorder = None

        return sorder

    def search_ml_order( self, order_id, meli=None, rjson=None ):
        mlorder = None

        return mlorder

    def search_meli_product( self, meli=None, meli_item=None, config=None ):
        product_obj = self.env['product.product']
        if not meli_item:
            return None
        meli_id = meli_item['id']
        meli_id_variation = ("variation_id" in meli_item and meli_item['variation_id'])
        if (meli_id_variation):
            product_related = product_obj.search([ ('meli_id','=',meli_id), ('meli_id_variation','=',meli_id_variation) ])
        else:
            product_related = product_obj.search([('meli_id','=', meli_id)])
        return product_related


    def orders_update_order_json( self, data, context=None, config=None, meli=None ):

        _logger.info("orders_update_order_json > data "+str(data['id']) + " json:" + str(data['order_json']['id']) )

        oid = data["id"]
        order_json = data["order_json"]
        #_logger.info( "data:" + str(data) )
        company = self.env.user.company_id
        if not config:
            config = company
        if not meli:
            meli = self.env['meli.util'].get_new_instance(company)

        saleorder_obj = self.env['sale.order']
        saleorderline_obj = self.env['sale.order.line']
        product_obj = self.env['product.product']

        pricelist_obj = self.env['product.pricelist']
        respartner_obj = self.env['res.partner']

        plistid = None
        if config.mercadolibre_pricelist:
            plistid = config.mercadolibre_pricelist
        else:
            plistids = pricelist_obj.search([])[0]
            if plistids:
                plistid = plistids

        order_obj = self.env['mercadolibre.orders']
        buyers_obj = self.env['mercadolibre.buyers']
        posting_obj = self.env['mercadolibre.posting']
        order_items_obj = self.env['mercadolibre.order_items']
        payments_obj = self.env['mercadolibre.payments']
        shipment_obj = self.env['mercadolibre.shipment']

        order = None
        sorder = None

        # if id is defined, we are updating existing one
        if (oid):
            order = order_obj.browse(oid )
            if (order):
                _logger.info(order)
                sorder_s = saleorder_obj.search([ ('meli_order_id','=',order.order_id) ] )
                if (sorder_s):
                    _logger.info(sorder_s)
                    if (len(sorder_s)>1):
                        sorder = sorder_s[0]
                    else:
                        sorder = sorder_s
        else:
        #we search for existing order with same order_id => "id"
            order_s = order_obj.search([ ('order_id','=','%s' % (str(order_json["id"]))) ] )
            if (order_s):
                if (len(order_s)>1):
                    order = order_s[0]
                else:
                    order = order_s
            #    order = order_obj.browse(order_s[0] )

            sorder_s = saleorder_obj.search([ ('meli_order_id','=','%s' % (str(order_json["id"]))) ] )
            if (sorder_s):
                if (len(sorder_s)>1):
                    sorder = sorder_s[0]
                else:
                    sorder = sorder_s
            #if (sorder_s and len(sorder_s)>0):
            #    sorder = saleorder_obj.browse(sorder_s[0] )
        seller_id = None
        if config.mercadolibre_seller_user:
            seller_id = config.mercadolibre_seller_user.id

        order_fields = self.prepare_ml_order_vals( order_json=order_json, meli=meli, config=config )

        partner_id = False
        partner_shipping_id = False

        if 'buyer' in order_json:
            Buyer = order_json['buyer']
            Receiver = False
            if ('shipping' in order_json):
                if ('receiver_address' in order_json['shipping']):
                    Receiver = order_json['shipping']['receiver_address']
                elif ('id' in order_json['shipping']):
                    Shipment = self.env["mercadolibre.shipment"].search([('shipping_id','=',order_json['shipping']["id"])])
                    if (len(Shipment)==1):
                        Receiver = {
                            'receiver_address': Shipment.receiver_address_line,
                            'country': {
                                'id': Shipment.receiver_country_code,
                                'name': Shipment.receiver_country
                            },
                            'state': {
                                'name': Shipment.receiver_state,
                                'id': Shipment.receiver_state_code
                            },
                            'city': {
                                'name': Shipment.receiver_city,
                                'id': Shipment.receiver_city_code
                            }
                        }
                    else:
                        shipres = meli.get("/shipments/"+ str(order_json['shipping']['id']),  {'access_token':meli.access_token })
                        if shipres:
                            shpjson = shipres.json()
                            if "receiver_address" in shpjson:
                                Receiver = shpjson["receiver_address"]

            meli_buyer_fields = {
                'name': Buyer['first_name']+' '+Buyer['last_name'],
                'street': self.street(Receiver),
                'city': self.city(Receiver),
                'country_id': self.country(Receiver),
                'state_id': self.state(self.country(Receiver),Receiver),
                'phone': self.full_phone( Buyer ),
                #'email': Buyer['email'],
                'meli_buyer_id': Buyer['id']
            }

            if "l10n_co_cities.city" in self.env:
                state_id = meli_buyer_fields["state_id"]
                city = self.env["l10n_co_cities.city"].search([('city_name','like',meli_buyer_fields["city"])])

                if not city and state_id:
                    _logger.warning("City not found: " + str(state_id))
                    _logger.info("Search first city for state: " + str(state_id))
                    city = self.env["l10n_co_cities.city"].search([('state_id','=',state_id)])

                if city:
                    _logger.info(city)
                    city = city[0]

                    _logger.info("Founded cities for state: " + str(state_id)+ " city_name: "+str(city.city_name))

                    meli_buyer_fields["cities"] = city.id

                    postal = self.env["l10n_co_postal.postal_code"].search([('city_id','=',city.id)])
                    if postal:
                        postal = postal[0]
                        meli_buyer_fields["postal_id"] = postal.id
                    else:
                        _logger.error("Postal code not found for: " + str(city.city_name)+ "["+str(city.id)+"]")
                else:
                    _logger.error("City not found for: " + str(meli_buyer_fields["city"]))


            buyer_fields = {
                'name': Buyer['first_name']+' '+Buyer['last_name'],
                'buyer_id': Buyer['id'],
                'nickname': Buyer['nickname'],
                'email': Buyer['email'],
                'phone': self.full_phone( Buyer ),
                'alternative_phone': self.full_alt_phone( Buyer ),
                'first_name': Buyer['first_name'],
                'last_name': Buyer['last_name'],
                'billing_info': self.billing_info(Buyer['billing_info']),
            }
            if ('doc_type' in Buyer['billing_info']):
                buyer_fields['billing_info_doc_type'] = Buyer['billing_info']['doc_type']
                if ('doc_number' in Buyer['billing_info']):
                    buyer_fields['billing_info_doc_number'] = Buyer['billing_info']['doc_number']
            else:
                buyer_fields['billing_info_doc_type'] = ''
                buyer_fields['billing_info_doc_number'] = ''


            buyer_ids = buyers_obj.search([  ('buyer_id','=',buyer_fields['buyer_id'] ) ] )
            buyer_id = 0
            if (buyer_ids==False or len(buyer_ids)==0):
                _logger.info( "creating buyer")
                _logger.info(buyer_fields)
                buyer_id = buyers_obj.create(( buyer_fields ))
            else:
                buyer_id = buyer_ids
                buyer_id.write( ( buyer_fields ) )
                #if (len(buyer_ids)>0):
                #      buyer_id = buyer_ids[0]
            if (buyer_id):
                meli_buyer_fields['meli_buyer'] = buyer_id.id
                if (('doc_type' in Buyer['billing_info']) and ('afip.responsability.type' in self.env)):
                    doctypeid = self.env['res.partner.id_category'].search([('code','=',Buyer['billing_info']['doc_type'])]).id
                    if (doctypeid):
                        meli_buyer_fields['main_id_category_id'] = doctypeid
                        meli_buyer_fields['main_id_number'] = Buyer['billing_info']['doc_number']
                        if (Buyer['billing_info']['doc_type']=="CUIT"):
                            #IVA Responsable Inscripto
                            afipid = self.env['afip.responsability.type'].search([('code','=',1)]).id
                            meli_buyer_fields["afip_responsability_type_id"] = afipid
                        else:
                            #if (Buyer['billing_info']['doc_type']=="DNI"):
                            #Consumidor Final
                            afipid = self.env['afip.responsability.type'].search([('code','=',5)]).id
                            meli_buyer_fields["afip_responsability_type_id"] = afipid
                    else:
                        _logger.error("res.partner.id_category:" + str(Buyer['billing_info']['doc_type']))


                #Chile
                if ( ('doc_type' in Buyer['billing_info']) and ('l10n_latam_identification_type_id' in self.env['res.partner']._fields) ):
                    if (Buyer['billing_info']['doc_type']=="RUT"):
                        meli_buyer_fields['l10n_latam_identification_type_id'] = 4
                    if (Buyer['billing_info']['doc_type']=="RUN"):
                        meli_buyer_fields['l10n_latam_identification_type_id'] = 5

                    meli_buyer_fields['vat'] = Buyer['billing_info']['doc_number']


                #Colombia
                if ( ('doc_type' in Buyer['billing_info']) and ('l10n_co_document_type' in self.env['res.partner']._fields) ):
                    if ("fe_es_compania" in self.env['res.partner']._fields ):
                        meli_buyer_fields['fe_es_compania'] = '2'
                    if ("fe_correo_electronico" in self.env['res.partner']._fields ):
                        meli_buyer_fields['fe_correo_electronico'] = Buyer['email']

                    if (Buyer['billing_info']['doc_type']=="CC" or Buyer['billing_info']['doc_type']=="C.C."):
                        meli_buyer_fields['l10n_co_document_type'] = 'national_citizen_id'
                        if ("fe_tipo_documento" in self.env['res.partner']._fields):
                            meli_buyer_fields['fe_tipo_documento'] = '13'
                        if ("fe_tipo_regimen" in self.env['res.partner']._fields ):
                            meli_buyer_fields['fe_tipo_regimen'] = '00'
                        if ("fe_regimen_fiscal" in self.env['res.partner']._fields ):
                            meli_buyer_fields['fe_regimen_fiscal'] = '49'
                        if ("responsabilidad_fiscal_fe" in self.env['res.partner']._fields ):
                            meli_buyer_fields['responsabilidad_fiscal_fe'] = [ ( 6, 0, [29] ) ]

                    if (Buyer['billing_info']['doc_type']=="NIT"):
                        meli_buyer_fields['l10n_co_document_type'] = 'rut'
                        if ("fe_tipo_documento" in self.env['res.partner']._fields):
                            meli_buyer_fields['fe_tipo_documento'] = '31'
                        if ("fe_es_compania" in self.env['res.partner']._fields ):
                            meli_buyer_fields['fe_es_compania'] = '1'
                        #if ("fe_tipo_regimen" in self.env['res.partner']._fields ):
                        #    meli_buyer_fields['fe_tipo_regimen'] = '04'
                        #if ("fe_regimen_fiscal" in self.env['res.partner']._fields ):
                        #    meli_buyer_fields['fe_regimen_fiscal'] = '48'

                    if (Buyer['billing_info']['doc_type']=="CE"):
                        meli_buyer_fields['l10n_co_document_type'] = 'foreign_id_card'
                        if ("fe_tipo_documento" in self.env['res.partner']._fields):
                            meli_buyer_fields['fe_tipo_documento'] = '22'
                        if ("fe_tipo_regimen" in self.env['res.partner']._fields ):
                            meli_buyer_fields['fe_tipo_regimen'] = '00'
                        if ("fe_regimen_fiscal" in self.env['res.partner']._fields ):
                            meli_buyer_fields['fe_regimen_fiscal'] = '49'
                        if ("responsabilidad_fiscal_fe" in self.env['res.partner']._fields ):
                            meli_buyer_fields['responsabilidad_fiscal_fe'] = [ ( 6, 0, [29] ) ]

                    meli_buyer_fields['vat'] = Buyer['billing_info']['doc_number']
                    if ("fe_nit" in self.env['res.partner']._fields):
                        meli_buyer_fields['fe_nit'] = Buyer['billing_info']['doc_number']
                        if (Buyer['billing_info']['doc_type']=="NIT"):
                            meli_buyer_fields['fe_nit'] = Buyer['billing_info']['doc_number'][0:10]
                            if ("fe_digito_verificacion" in self.env['res.partner']._fields):
                                meli_buyer_fields['fe_digito_verificacion'] = Buyer['billing_info']['doc_number'][-1]

                    if ("fe_primer_nombre" in self.env['res.partner']._fields):
                        nn = Buyer['first_name'].split(" ")
                        if (len(nn)>1):
                            meli_buyer_fields['fe_primer_nombre'] = nn[0]
                            meli_buyer_fields['fe_segundo_nombre'] = nn[1]
                        else:
                            meli_buyer_fields['fe_primer_nombre'] = Buyer['first_name']
                    if ("fe_primer_apellido" in self.env['res.partner']._fields):
                        nn = Buyer['last_name'].split(" ")
                        if (len(nn)>1):
                            meli_buyer_fields['fe_primer_apellido'] = nn[0]
                            meli_buyer_fields['fe_segundo_apellido'] = nn[1]
                        else:
                            meli_buyer_fields['fe_primer_apellido'] = Buyer['last_name']


            partner_ids = respartner_obj.search([  ('meli_buyer_id','=',buyer_fields['buyer_id'] ) ] )
            if (len(partner_ids)>0):
                partner_id = partner_ids[0]
            if ("fe_regimen_fiscal" in self.env['res.partner']._fields):
                if (partner_id and not partner_id.fe_regimen_fiscal):
                    meli_buyer_fields['fe_regimen_fiscal'] = '49';
                else:
                    meli_buyer_fields['fe_regimen_fiscal'] = '49';
            if not partner_id:
                #_logger.info( "creating partner:" + str(meli_buyer_fields) )
                partner_id = respartner_obj.create(( meli_buyer_fields ))
            else:
                partner_id = partner_ids[0]
                _logger.info("Updating partner (do not update principal, always create new one)")
                _logger.info(meli_buyer_fields)
                #complete country at most:
                partner_update = {}
                if not partner_id.country_id:
                    partner_update.update({'country_id': self.country(Receiver)})
                if not partner_id.state_id:
                    partner_update.update({ 'state_id': self.state(self.country(Receiver), Receiver)})
                if partner_update:
                    _logger.info("Updating:"+str(partner_update))
                    partner_id.write(partner_update)


                if (partner_id.email and (partner_id.email==buyer_fields["email"] or "mercadolibre.com" in partner_id.email)):
                    #eliminar email de ML que no es valido
                    meli_buyer_fields["email"] = ''
                #crear nueva direccion de entrega
                #partner_id.write( meli_buyer_fields )

            if (partner_id and 1==2):
                pdelivery_fields = {
                    "type": "delivery",
                    "parent_id": partner_id.id,
                    'name': meli_buyer_fields['name'],
                    'street': meli_buyer_fields['street'],
                    #'street2': meli_buyer_fields['name'],
                    'city': meli_buyer_fields['city'],
                    'country_id': meli_buyer_fields['country_id'],
                    'state_id': meli_buyer_fields['state_id'],
                    #'zip': meli_buyer_fields['name'],
                    #"comment": ("location_addressNotes" in contactfields and contactfields["location_addressNotes"]) or ""
                    #'producteca_bindings': [(6, 0, [client.id])]
                    #'phone': self.full_phone( contactfields,billing=True ),
                    #'email':contactfields['billingInfo_email'],
                    #'producteca_bindings': [(6, 0, [client.id])]
                }
{'fraction_non_alphanumeric': 0.12169647096059504, 'fraction_numerical': 0.004402307614841243, 'mean_word_length': 1.8804077573346594, 'pattern_counts': {'":': 12, '<': 11, '<?xml version=': 0, '>': 35, 'https://': 0, 'lorem ipsum': 0, 'www.': 2, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 20, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '3168948', 'n_tokens_mistral': 21280, 'n_tokens_neox': 20071, 'n_words': 3641}