package cn.ibizlab.businesscentral.core.extensions.service;

import cn.ibizlab.businesscentral.core.odoo_account.domain.Account_move;
import cn.ibizlab.businesscentral.core.odoo_base.domain.Res_company;
import cn.ibizlab.businesscentral.core.odoo_base.domain.Res_currency;
import cn.ibizlab.businesscentral.core.odoo_base.domain.Res_partner;
import cn.ibizlab.businesscentral.core.odoo_ir.domain.Ir_sequence;
import cn.ibizlab.businesscentral.core.odoo_product.domain.Product_product;
import cn.ibizlab.businesscentral.core.odoo_product.domain.Product_supplierinfo;
import cn.ibizlab.businesscentral.core.odoo_product.domain.Product_template;
import cn.ibizlab.businesscentral.core.odoo_purchase.domain.Account_move_purchase_order_rel;
import cn.ibizlab.businesscentral.core.odoo_purchase.domain.Purchase_order_line;
import cn.ibizlab.businesscentral.core.odoo_purchase.service.impl.Purchase_orderServiceImpl;
import cn.ibizlab.businesscentral.core.odoo_uom.domain.Uom_uom;
import lombok.extern.slf4j.Slf4j;
import cn.ibizlab.businesscentral.core.odoo_purchase.domain.Purchase_order;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.context.annotation.Primary;

import java.sql.Timestamp;
import java.time.LocalDate;
import java.util.*;

/**
 * 实体[采购订单] 自定义服务对象
 */
@Slf4j
@Primary
@Service("Purchase_orderExService")
public class Purchase_orderExService extends Purchase_orderServiceImpl {

    @Autowired
    protected cn.ibizlab.businesscentral.core.odoo_account.service.IAccount_moveService accountMoveService;

    @Autowired
    protected cn.ibizlab.businesscentral.core.odoo_product.service.IProduct_productService productService;

    @Autowired
    protected cn.ibizlab.businesscentral.core.odoo_product.service.IProduct_templateService productTemplateService;

    @Autowired
    protected cn.ibizlab.businesscentral.core.odoo_ir.service.IIr_sequenceService sequenceService;

    @Autowired
    protected cn.ibizlab.businesscentral.core.odoo_product.service.IProduct_supplierinfoService productSupplierinfoService;

    @Autowired
    protected  cn.ibizlab.businesscentral.core.odoo_uom.service.IUom_uomService uomService;

    @Override
    protected Class currentModelClass() {
        return com.baomidou.mybatisplus.core.toolkit.ReflectionKit.getSuperClassGenericType(this.getClass().getSuperclass(), 1);
    }

    /**
     * 自定义行为[Button_cancel]用户扩展
     * @param et
     * @return
     */
    @Override
    @Transactional
    public Purchase_order button_cancel(Purchase_order et) {
        // 获取凭证录入的ID组
        List<Account_move_purchase_order_rel> accountMovePurchaseOrderRels = accountMovePurchaseOrderRelService.selectByPurchaseOrderId(et.getId());
        List<String> accountMoveIds = new ArrayList();
        for(Account_move_purchase_order_rel accountMovePurchaseOrderRel : accountMovePurchaseOrderRels){
            accountMoveIds.add(accountMovePurchaseOrderRel.getAccountMoveId().toString());
        }
        // 通过凭证录入的ID获取对应的凭证记录
        List<Account_move> accountMoves = accountMoveService.getAccountMoveByIds(accountMoveIds);
        for(Account_move accountMove : accountMoves){
            if(StringUtils.compare(accountMove.getState(),"cancel")==0|| StringUtils.compare(accountMove.getState(),"draft")==0){
                throw new RuntimeException("无法取消此采购订单。 您必须先取消相关的供应商账单。") ;
            }
        }
        et.setState("cancel");
        this.update(et);
        return super.button_cancel(et);
    }
    /**
     * 自定义行为[Button_confirm]用户扩展
     * @param et
     * @return
     */
    @Override
    @Transactional
    public Purchase_order button_confirm(Purchase_order et) {
        if(StringUtils.compare(et.getState(), "draft") == 0 || StringUtils.compare(et.getState(), "sent") == 0){
            // 链接_add_supplier_to_product()
            /**
             * 如果供应商未注册此产品，则将合作伙伴添加到该产品的供应商列表中。
             * 限制一个产品的供应商数量为10家，以避免一些通用产品(“杂项”)可能造成的混乱。
             */
            // 获取该采购订单对应的采购订单行记录
            List<Purchase_order_line> lines = purchaseOrderLineService.selectByOrderId(et.getId());
            for(Purchase_order_line line : lines){
                /**
                 * 将联系人partner或联系人的上级作为供应商
                 * 当联系人存在上级时，将联系人的上级作为供应商
                 * 当联系人不存在所属公司时，直接将联系人作为供应商
                 */
                Res_partner partner = resPartnerService.get(line.getPartnerId());
                if(partner.getParentId() != null){
                    partner = resPartnerService.get(partner.getParentId());
                }
                // 获取Product_product的供应商
                Product_product product = productService.getById(line.getProductId());
                // if判断的条件2
                Boolean condition2 = true;
                // 根据产品供应商信息表product_supplierinfo查找当前的供应商是否已存在,从表里查
                List<Product_supplierinfo> supplierinfos = productSupplierinfoService.selectByProductId(line.getProductId());
                for(Product_supplierinfo supplierinfo : supplierinfos){
                    if(partner.getId() == supplierinfo.getName()){
                        condition2 = false;
                    }
                }
                // 判断是否将当前的供应商加入产品供应商信息表product_supplierinfo中
                if(line.getProductId() != null && condition2 && supplierinfos.size() <= 10){
                    // 获取币种currency
                    Res_currency Currency = new Res_currency();
                    if(partner.getPropertyPurchaseCurrencyId() !=null && et.getCurrencyId() != null){
                        Currency = resCurrencyService.getById(partner.getPropertyPurchaseCurrencyId());
                    }else if(partner.getPropertyPurchaseCurrencyId() !=null && et.getCurrencyId() == null){
                        Currency = resCurrencyService.getById(partner.getPropertyPurchaseCurrencyId());
                    }else if(partner.getPropertyPurchaseCurrencyId() ==null && et.getCurrencyId() != null){
                        Currency = resCurrencyService.getById(partner.getPropertyPurchaseCurrencyId());
                    }
                    // 将price转换成当前所用币种的price，还未处理，需要调用Res_currency中的_convert()方法
                    Double price = line.getPriceUnit();
                    /**
                    // _convert()方法
                    // 传入参数
                    Double from_amount = line.getPriceUnit();
                    Long toCurrency =  Currency.getId();
                    Long company = line.getCompanyId();
                    Timestamp date = line.getDateOrder() != null ? et.getDateOrder() : new Timestamp(System.currentTimeMillis());
                    Boolean round = false;
                    // 函数处理内容
                    if(et.getCurrencyId() == toCurrency){
                        price = from_amount;
                    }else{
//                        price = line.getPriceUnit() *
                    }
                     */

                    // 计算模板的UoM的价格，因为供应商的UoM与该UoM相关
                    Product_template productTemplate = productTemplateService.get(product.getProductTmplId());
                    if(productTemplate.getUomPoId() != line.getProductUom()){
                        Long default_uom = productTemplate.getUomPoId();
                        // 计算price, 暂未处理,需要调用uom_uom.py中的_compute_price()方法
                    }
                    // 创建供应商价格表记录
                    Product_supplierinfo supplierinfo = new Product_supplierinfo();
                    supplierinfo.setName(partner.getId());
                    // 设置序号sequence,若是第一个则为1，若不是则取最大sequence+1
                    Integer sequence = 1;
                    if(supplierinfos.size() != 0){
                        Integer maxSequence = 0;
                        // 拿到sellerIds对应的一系列sequence,取最大的序号+1
                        for(Product_supplierinfo supplierinfo1 : supplierinfos){
                            maxSequence = maxSequence > supplierinfo1.getSequence() ? maxSequence : supplierinfo1.getSequence();
                        }
                        sequence = maxSequence + 1;
                    }
                    supplierinfo.setSequence(sequence);
                    supplierinfo.setMinQty(0.0);
                    supplierinfo.setPrice(price);
                    supplierinfo.setCurrencyId(Currency.getId());
                    supplierinfo.setDelay(0);

                    // 按条件查找供应商
                    // 未处理，需要调用product.py中的_select_seller()方法'
//                    Product_supplierinfo seller = ;
                    /**
                    Long partnerId = line.getPartnerId();
                    Double quantity = line.getProductQty();
                    Timestamp date = et.getDateOrder();
                    Long uomId = line.getProductUom();
                    if(date == null){
                        date = new Timestamp(System.currentTimeMillis());
                    }

                    // precision,decimal_precision.py中的precision_get()方法
                    Integer precision = 3;

                    // sellers = self._prepare_sellers(params) product.py中的_prepare_sellers()方法
                    List<Product_supplierinfo> sellers = productSupplierinfoService.select();

                    for(Product_supplierinfo seller : sellers){
                        Double quantityUomSeller = quantity;
                        if(quantityUomSeller != 0.0 && uomId != null && uomId != seller.getProductUom()){
                            //调用uom_uom.py中的_compute_quantity()方法
                            Uom_uom uom1 = uomService.get(uomId);

                            Uom_uom uom2 = uomService.get(seller.getProductUom());
                            if(uom1.getCategoryId() != uom2.getCategoryId()){
                                if(true){
                                    throw new RuntimeException("无法取消此采购订单。 您必须先取消相关的供应商账单。") ;
                                }else {
                                    quantityUomSeller = quantityUomSeller;
                                }
                            }
                            Double amount = quantityUomSeller / uom1.getFactor();
                            if(seller.getProductUom() != null){
                                amount = amount * uom2.getFactor();
//                                if(true)
                                    // 调用float_utils.py中的float_round()方法,未处理
//                                    amount =
                            }
                            quantityUomSeller = amount;
                        }
                        if(seller.getDateStart() !=null && seller.getDateStart().getTime() > date.getTime())
                            continue;
                        if(seller.getDateEnd() != null && seller.getDateEnd().getTime() < date.getTime())
                            continue;
                        Res_partner resPartner = resPartnerService.get(partnerId);
                        if(partnerId != null && seller.getName() != partnerId && seller.getName() != resPartner.getParentId())
                            continue;
                        // float_compare()方法，float_utils.py中的

                        if(seller.getProductId() != null && )
                            continue;
                    }
                    */
                    // 若找到了同样的供应商
//                    if(seller){
//                        supplierinfo.setProductName(seller.getProductName());
//                        supplierinfo.setProductCode(seller.getProductCode());
//                    }
                    // 将新的供应商价格写入供应商价格表k
                    productSupplierinfoService.create(supplierinfo);
                }
            }
            Res_company resCompany = resCompanyService.get(et.getCompanyId());
            // if判断三个条件
            Boolean condition1 = StringUtils.compare(resCompany.getPoDoubleValidation(), "one_step") == 0;
            // 暂未处理，这里需要需要调用Res_currency 中的_convert()方法
            Boolean condition2 = false;
//            Boolean condition2 = StringUtils.compare(resCompany.getPoDoubleValidation(), "two_step")==0 && et.getAmountTotal() < ;
            // 这里需要调用odoo/models.py中的user_has_groups()方法,暂未处理
            Boolean condition3 = false;
            // 处理双重验证过程
            if( condition1 || condition2 || condition3){
                // 调用button_approve()
                et = this.button_approve(et);
                log.warn("button_approve()");
            }else{
                et.setState("to approve");
            }
        }
        this.update(et);
        return super.button_confirm(et);
    }
    /**
     * 自定义行为[Button_done]用户扩展
     * @param et
     * @return
     */
    @Override
    @Transactional
    public Purchase_order button_done(Purchase_order et) {
        // 改变采购订单的状态为锁定
        et.setState("done");
        this.update(et);
        return super.button_done(et);
    }
    /**
     * 自定义行为[Button_unlock]用户扩展
     * @param et
     * @return
     */
    @Override
    @Transactional
    public Purchase_order button_unlock(Purchase_order et) {
        // 改变采购订单的状态为解锁
        et.setState("purchase");
        this.update(et);
        return super.button_unlock(et);
    }
    /**
     * 自定义行为[Get_name]用户扩展
     * @param et
     * @return
     */
    @Override
    @Transactional
    public Purchase_order get_name(Purchase_order et) {
        // 当订单的name是new时自动为其创建一个name
        if(StringUtils.compare(et.getName(), "new") == 0){
            if(et.getDateOrder() != null){
                // sequence_date
                Ir_sequence sequence = new Ir_sequence();
                sequenceService.get_next_by_code(sequence);
                et.setName(sequence.getNextChar());
            }
        }
        return super.get_name(et);
    }

    /**
     * 自定义行为[Button_approve]用户扩展
     * @param et
     * @return
     */
    @Override
    @Transactional
    public Purchase_order button_approve(Purchase_order et) {
        et.setState("purchase");
        Timestamp dateApprove = new Timestamp(System.currentTimeMillis());
        et.setDateApprove(dateApprove);
        this.update(et);
        // 查找order中公司的po_lock状态为lock的order,改变状态为done,有疑问
        Res_company resCompany = resCompanyService.get(et.getCompanyId());
        if(StringUtils.compare(resCompany.getPoLock(), "lock") == 0){
            et.setState("done");
            this.update(et);
        }
        return super.button_approve(et);
    }
}

