@Override
  public SupplierInfoChangedDto paperworkChanged(
      Long userId, PaperworkDto updatedPaperwork, Company oldPaperwork) {
    SupplierInfoChangedDto supplierInfoChangedDto = new SupplierInfoChangedDto();

    Map<String, String> changedInfo = Maps.newHashMap();

    int type = CountryCertificate.check(oldPaperwork.getRegCountry());

    PaperworkDto newPaperworkDto = getNewPaperwork(userId, oldPaperwork).getSupplierInfo();

    switch (type) {
      case CountryCertificate.NO_CERTIFICATE:
        supplierInfoChangedDto.setChanged(false);
        return supplierInfoChangedDto;
      case CountryCertificate.ONLY_NEED_BUSINESS_LICENSE:
        checkBusinessLicense(changedInfo, updatedPaperwork, newPaperworkDto);
        break;
      case CountryCertificate.ONLY_NEED_BUSINESS_LICENSE_AND_TAX_NO:
        checkBusinessLicense(changedInfo, updatedPaperwork, newPaperworkDto);
        checkTaxNo(changedInfo, updatedPaperwork, newPaperworkDto);
        break;
      default:
        checkBusinessLicense(changedInfo, updatedPaperwork, newPaperworkDto);
        checkTaxNo(changedInfo, updatedPaperwork, newPaperworkDto);
        checkOrgCert(changedInfo, updatedPaperwork, newPaperworkDto);
    }

    if (!changedInfo.isEmpty()) {
      supplierInfoChangedDto.setChanged(true);
      supplierInfoChangedDto.setChangedInfo(changedInfo);
    }

    return supplierInfoChangedDto;
  }
  @Override
  public SupplierInfoChangedDto financeChanged(
      Long userId, Finance updatedFinance, Finance oldFinance) {
    SupplierInfoChangedDto supplierInfoChangedDto = new SupplierInfoChangedDto();

    Finance newFinance = getNewFinance(userId, oldFinance).getSupplierInfo();

    Map<String, String> changedInfo = Maps.newHashMap();

    if (!Objects.equal(updatedFinance.getCountry(), newFinance.getCountry())) {
      changedInfo.put(
          ChangedInfoKeys.financeCountry(), String.valueOf(updatedFinance.getCountry()));
      updatedFinance.setCountry(null);
    }
    if (!Objects.equal(updatedFinance.getBankAccount(), newFinance.getBankAccount())) {
      changedInfo.put(ChangedInfoKeys.financeBankAccount(), updatedFinance.getBankAccount());
      updatedFinance.setBankAccount(null);
    }
    if (!Objects.equal(updatedFinance.getBankCode(), newFinance.getBankCode())) {
      changedInfo.put(ChangedInfoKeys.financeBankCode(), updatedFinance.getBankCode());
      updatedFinance.setBankCode(null);
    }
    if (!Objects.equal(updatedFinance.getCoinType(), newFinance.getCoinType())) {
      changedInfo.put(
          ChangedInfoKeys.financeCoinType(), String.valueOf(updatedFinance.getCoinType()));
      updatedFinance.setCoinType(null);
    }
    if (!Objects.equal(updatedFinance.getOpenLicense(), newFinance.getOpenLicense())) {
      changedInfo.put(ChangedInfoKeys.financeOpenLicense(), updatedFinance.getOpenLicense());
      updatedFinance.setOpenLicense(null);
    }
    if (!Objects.equal(updatedFinance.getRecentFinance(), newFinance.getRecentFinance())) {
      changedInfo.put(ChangedInfoKeys.financeRecentFinance(), updatedFinance.getRecentFinance());
      updatedFinance.setRecentFinance(null);
    }
    if (!Objects.equal(updatedFinance.getOpeningBank(), newFinance.getOpeningBank())) {
      changedInfo.put(ChangedInfoKeys.financeOpeningBank(), updatedFinance.getOpeningBank());
      updatedFinance.setOpeningBank(null);
    }

    if (!changedInfo.isEmpty()) {
      supplierInfoChangedDto.setChanged(true);
      supplierInfoChangedDto.setChangedInfo(changedInfo);
    }

    return supplierInfoChangedDto;
  }
  public SupplierInfoChangedDto contactInfoChanged(
      Long userId, ContactInfo updatedContactInfo, ContactInfo oldContactInfo) {
    SupplierInfoChangedDto supplierInfoChangedDto = new SupplierInfoChangedDto();

    ContactInfo newContactInfo = getNewContactInfo(userId, oldContactInfo).getSupplierInfo();

    Map<String, String> changedInfo = Maps.newHashMap();

    if (!Objects.equal(updatedContactInfo.getName(), newContactInfo.getName())) {
      changedInfo.put(ChangedInfoKeys.contactInfoName(), updatedContactInfo.getName());
      updatedContactInfo.setName(null);
    }

    if (!Objects.equal(updatedContactInfo.getEmail(), newContactInfo.getEmail())) {
      changedInfo.put(ChangedInfoKeys.contactInfoEmail(), updatedContactInfo.getEmail());
      updatedContactInfo.setEmail(null);
    }

    if (!Objects.equal(updatedContactInfo.getMobile(), newContactInfo.getMobile())) {
      changedInfo.put(ChangedInfoKeys.contactInfoMobile(), updatedContactInfo.getMobile());
      updatedContactInfo.setMobile(null);
    }

    Company company = companyDao.findByUserId(userId);
    if (!Strings.isNullOrEmpty(company.getSupplierCode())) {
      if (!Objects.equal(updatedContactInfo.getOfficePhone(), newContactInfo.getOfficePhone())) {
        changedInfo.put(ChangedInfoKeys.contactInfoPhone(), updatedContactInfo.getOfficePhone());
        updatedContactInfo.setOfficePhone(null);
      }
    }

    if (!changedInfo.isEmpty()) {
      supplierInfoChangedDto.setChanged(true);
      supplierInfoChangedDto.setChangedInfo(changedInfo);
    }
    return supplierInfoChangedDto;
  }
  @Override
  public SupplierInfoChangedDto qualityChanged(
      Long userId, CompanyExtraQuality updatedQuality, CompanyExtraQuality oldQuality) {
    SupplierInfoChangedDto supplierInfoChangedDto = new SupplierInfoChangedDto();

    CompanyExtraQuality newQuality =
        getNewCompanyExtraQuality(userId, oldQuality).getSupplierInfo();

    Map<String, String> changedInfo = Maps.newHashMap();

    if (!Objects.equal(updatedQuality.getRohsId(), newQuality.getRohsId())) {
      changedInfo.put(ChangedInfoKeys.qualityRohsId(), updatedQuality.getRohsId());
      updatedQuality.setRohsId(null);
    }
    if (!Objects.equal(updatedQuality.getRohsAttachUrl(), newQuality.getRohsAttachUrl())) {
      changedInfo.put(ChangedInfoKeys.qualityRohsAttachUrl(), updatedQuality.getRohsAttachUrl());
      updatedQuality.setRohsAttachUrl(null);
    }

    if (updatedQuality.getRohsValidDate() != null) {
      DateTime updatedRohsValidDate = new DateTime(updatedQuality.getRohsValidDate());
      if (newQuality.getRohsValidDate() == null) {
        changedInfo.put(
            ChangedInfoKeys.qualityRohsValidDate(), updatedRohsValidDate.toString(FORMATTER));
        updatedQuality.setRohsValidDate(null);
      } else {
        DateTime oldRohsValidDate = new DateTime(newQuality.getRohsValidDate());
        if (!updatedRohsValidDate.equals(oldRohsValidDate)) {
          changedInfo.put(
              ChangedInfoKeys.qualityRohsValidDate(), updatedRohsValidDate.toString(FORMATTER));
          updatedQuality.setRohsValidDate(null);
        }
      }
    }

    if (!Objects.equal(updatedQuality.getIso9001Id(), newQuality.getIso9001Id())) {
      changedInfo.put(ChangedInfoKeys.qualityISO9001Id(), updatedQuality.getIso9001Id());
      updatedQuality.setIso9001Id(null);
    }
    if (!Objects.equal(updatedQuality.getIso9001AttachUrl(), newQuality.getIso9001AttachUrl())) {
      changedInfo.put(
          ChangedInfoKeys.qualityISO9001AttachUrl(), updatedQuality.getIso9001AttachUrl());
      updatedQuality.setIso9001AttachUrl(null);
    }

    if (updatedQuality.getIso9001ValidDate() != null) {
      DateTime updatedIso9001ValidDate = new DateTime(updatedQuality.getIso9001ValidDate());
      if (newQuality.getIso9001ValidDate() == null) {
        changedInfo.put(
            ChangedInfoKeys.qualityISO9001ValidDate(), updatedIso9001ValidDate.toString(FORMATTER));
        updatedQuality.setIso9001ValidDate(null);
      } else {
        DateTime oldIso9001ValidDate = new DateTime(newQuality.getIso9001ValidDate());
        if (!updatedIso9001ValidDate.equals(oldIso9001ValidDate)) {
          changedInfo.put(
              ChangedInfoKeys.qualityISO9001ValidDate(),
              updatedIso9001ValidDate.toString(FORMATTER));
          updatedQuality.setIso9001ValidDate(null);
        }
      }
    }

    if (!Objects.equal(updatedQuality.getIso14001Id(), newQuality.getIso14001Id())) {
      changedInfo.put(ChangedInfoKeys.qualityISO14001Id(), updatedQuality.getIso14001Id());
      updatedQuality.setIso14001Id(null);
    }
    if (!Objects.equal(updatedQuality.getIso14001AttachUrl(), newQuality.getIso14001AttachUrl())) {
      changedInfo.put(
          ChangedInfoKeys.qualityISO14001AttachUrl(), updatedQuality.getIso14001AttachUrl());
      updatedQuality.setIso14001AttachUrl(null);
    }

    if (updatedQuality.getIso14001ValidDate() != null) {
      DateTime updatedIso14001ValidDate = new DateTime(updatedQuality.getIso14001ValidDate());
      if (newQuality.getIso14001ValidDate() == null) {
        changedInfo.put(
            ChangedInfoKeys.qualityISO14001ValidDate(),
            updatedIso14001ValidDate.toString(FORMATTER));
        updatedQuality.setIso14001ValidDate(null);
      } else {
        DateTime oldIso14001ValidDate = new DateTime(newQuality.getIso14001ValidDate());
        if (!updatedIso14001ValidDate.equals(oldIso14001ValidDate)) {
          changedInfo.put(
              ChangedInfoKeys.qualityISO14001ValidDate(),
              updatedIso14001ValidDate.toString(FORMATTER));
          updatedQuality.setIso14001ValidDate(null);
        }
      }
    }

    if (!Objects.equal(updatedQuality.getTs16949Id(), newQuality.getTs16949Id())) {
      changedInfo.put(ChangedInfoKeys.qualityTS16949Id(), updatedQuality.getTs16949Id());
      updatedQuality.setTs16949Id(null);
    }
    if (!Objects.equal(updatedQuality.getTs16949AttachUrl(), newQuality.getTs16949AttachUrl())) {
      changedInfo.put(
          ChangedInfoKeys.qualityTS16949AttachUrl(), updatedQuality.getTs16949AttachUrl());
      updatedQuality.setTs16949AttachUrl(null);
    }

    if (updatedQuality.getTs16949ValidDate() != null) {
      DateTime updatedTs16949ValidDate = new DateTime(updatedQuality.getTs16949ValidDate());
      if (newQuality.getTs16949ValidDate() == null) {
        changedInfo.put(
            ChangedInfoKeys.qualityTS16949ValidDate(), updatedTs16949ValidDate.toString(FORMATTER));
        updatedQuality.setTs16949ValidDate(null);
      } else {
        DateTime oldTs16949ValidDate = new DateTime(newQuality.getTs16949ValidDate());
        if (!updatedTs16949ValidDate.equals(oldTs16949ValidDate)) {
          changedInfo.put(
              ChangedInfoKeys.qualityTS16949ValidDate(),
              updatedTs16949ValidDate.toString(FORMATTER));
          updatedQuality.setTs16949ValidDate(null);
        }
      }
    }

    if (!changedInfo.isEmpty()) {
      supplierInfoChangedDto.setChanged(true);
      supplierInfoChangedDto.setChangedInfo(changedInfo);
    }
    return supplierInfoChangedDto;
  }
  @Override
  public SupplierInfoChangedDto baseCompanyChanged(
      Long userId,
      CompanyDto updatedCompanyDto,
      Company oldCompany,
      List<CompanyMainBusiness> oldMainBusinesses,
      List<CompanySupplyPark> oldSupplyParks) {
    SupplierInfoChangedDto supplierInfoChangedDto = new SupplierInfoChangedDto();

    Company updatedCompany = updatedCompanyDto.getCompany();
    List<CompanyMainBusiness> updatedMainBusinesses = updatedCompanyDto.getCompanyMainBusinesses();
    List<CompanySupplyPark> updatedSupplyParks = updatedCompanyDto.getCompanySupplyParks();

    // 取出新的信息
    CompanyDto newCompanyDto =
        getNewBaseCompany(userId, oldCompany, oldMainBusinesses, oldSupplyParks).getSupplierInfo();
    Company newCompany = newCompanyDto.getCompany();
    List<CompanyMainBusiness> newMainBusinesses = newCompanyDto.getCompanyMainBusinesses();
    List<CompanySupplyPark> newSupplyParks = newCompanyDto.getCompanySupplyParks();

    Map<String, String> changedInfo = Maps.newHashMap();

    if (!Objects.equal(updatedCompany.getCorporation(), newCompany.getCorporation())) {
      changedInfo.put(ChangedInfoKeys.companyCorporation(), updatedCompany.getCorporation());
      updatedCompany.setCorporation(null);
    }

    if (!Objects.equal(updatedCompany.getInitAgent(), newCompany.getInitAgent())) {
      changedInfo.put(ChangedInfoKeys.companyInitAgent(), updatedCompany.getInitAgent());
      updatedCompany.setInitAgent(null);
    }

    if (!Objects.equal(updatedCompany.getDesc(), newCompany.getDesc())) {
      changedInfo.put(ChangedInfoKeys.companyDesc(), updatedCompany.getDesc());
      updatedCompany.setDesc(null);
    }

    if (!Objects.equal(updatedCompany.getRegCountry(), newCompany.getRegCountry())) {
      changedInfo.put(
          ChangedInfoKeys.companyRegCountry(), String.valueOf(updatedCompany.getRegCountry()));
      updatedCompany.setRegCountry(null);
    }

    //        if (!Objects.equal(company.getCustomers(), newCompany.getCustomers())) {
    //            changedInfo.put("", newCompany.getCustomers());
    //        }
    //
    if (!Objects.equal(updatedCompany.getProductLine(), newCompany.getProductLine())) {
      changedInfo.put(ChangedInfoKeys.companyProductLine(), updatedCompany.getProductLine());
    }

    if (mainBusinessChanged(updatedMainBusinesses, newMainBusinesses)) {
      changedInfo.put(
          ChangedInfoKeys.companyMainBusiness(),
          JsonMapper.nonEmptyMapper().toJson(updatedMainBusinesses));
    }

    if (supplyParkChanged(updatedSupplyParks, newSupplyParks)) {
      changedInfo.put(
          ChangedInfoKeys.companySupplyPark(),
          JsonMapper.nonEmptyMapper().toJson(updatedSupplyParks));
    }

    // 如果有V码,则继续检查合同信息
    if (!Strings.isNullOrEmpty(newCompany.getSupplierCode())) {

      if (!Objects.equal(updatedCompany.getGroupName(), newCompany.getGroupName())) {
        changedInfo.put(ChangedInfoKeys.companyGroupName(), updatedCompany.getGroupName());
        updatedCompany.setGroupName(null);
      }
      if (!Objects.equal(updatedCompany.getGroupAddr(), newCompany.getGroupAddr())) {
        changedInfo.put(ChangedInfoKeys.companyGroupAddr(), updatedCompany.getGroupAddr());
        updatedCompany.setGroupAddr(null);
      }
      if (!Objects.equal(updatedCompany.getRegCapital(), newCompany.getRegCapital())) {
        changedInfo.put(
            ChangedInfoKeys.companyRegCapical(), String.valueOf(updatedCompany.getRegCapital()));
        updatedCompany.setRegCapital(null);
      }
      if (!Objects.equal(updatedCompany.getRcCoinType(), newCompany.getRcCoinType())) {
        changedInfo.put(
            ChangedInfoKeys.companyRcCoinType(), String.valueOf(updatedCompany.getRcCoinType()));
        updatedCompany.setRcCoinType(null);
      }
      if (!Objects.equal(updatedCompany.getPersonScale(), newCompany.getPersonScale())) {
        changedInfo.put(ChangedInfoKeys.companyPersonScale(), updatedCompany.getPersonScale());
        updatedCompany.setPersonScale(null);
      }
      if (!Objects.equal(updatedCompany.getRegProvince(), newCompany.getRegProvince())) {
        changedInfo.put(
            ChangedInfoKeys.companyRegProvince(), String.valueOf(updatedCompany.getRegProvince()));
        updatedCompany.setRegProvince(null);
      }
      if (!Objects.equal(updatedCompany.getRegCity(), newCompany.getRegCity())) {
        changedInfo.put(
            ChangedInfoKeys.companyRegCity(), String.valueOf(updatedCompany.getRegCity()));
        updatedCompany.setRegCity(null);
      }
      if (!Objects.equal(updatedCompany.getFixedAssets(), newCompany.getFixedAssets())) {
        changedInfo.put(
            ChangedInfoKeys.companyFixedAssets(), String.valueOf(updatedCompany.getFixedAssets()));
        updatedCompany.setFixedAssets(null);
      }
      if (!Objects.equal(updatedCompany.getFaCoinType(), newCompany.getFaCoinType())) {
        changedInfo.put(
            ChangedInfoKeys.companyFaCoinType(), String.valueOf(updatedCompany.getFaCoinType()));
        updatedCompany.setFaCoinType(null);
      }

      Date updatedFoundAt = updatedCompany.getFoundAt();
      Date oldFoundAt = newCompany.getFoundAt();
      if (updatedFoundAt != null) {
        DateTime updated = new DateTime(updatedFoundAt);
        if (oldFoundAt == null) {
          changedInfo.put(ChangedInfoKeys.companyFoundAt(), updated.toString(FORMATTER));
          updatedCompany.setFoundAt(null);
        } else {
          DateTime old = new DateTime(oldFoundAt);
          if (!updated.equals(old)) {
            changedInfo.put(ChangedInfoKeys.companyFoundAt(), updated.toString(FORMATTER));
            updatedCompany.setFoundAt(null);
          }
        }
      }

      if (!Objects.equal(updatedCompany.getOfficialWebsite(), newCompany.getOfficialWebsite())) {
        changedInfo.put(
            ChangedInfoKeys.companyOfficialWebSite(), updatedCompany.getOfficialWebsite());
        updatedCompany.setOfficialWebsite(null);
      }
      if (!Objects.equal(updatedCompany.getNature(), newCompany.getNature())) {
        changedInfo.put(
            ChangedInfoKeys.companyNature(), String.valueOf(updatedCompany.getNature()));
        updatedCompany.setNature(null);
      }
      if (!Objects.equal(updatedCompany.getWorldTop(), newCompany.getWorldTop())) {
        changedInfo.put(
            ChangedInfoKeys.companyWorldTop(), String.valueOf(updatedCompany.getWorldTop()));
        updatedCompany.setWorldTop(null);
      }
      if (!Objects.equal(updatedCompany.getListedStatus(), newCompany.getListedStatus())) {
        changedInfo.put(
            ChangedInfoKeys.companyListedStatus(),
            String.valueOf(updatedCompany.getListedStatus()));
        updatedCompany.setListedStatus(null);
      }
      if (!Objects.equal(updatedCompany.getListedRegion(), newCompany.getListedRegion())) {
        changedInfo.put(ChangedInfoKeys.companyListedRegion(), updatedCompany.getListedRegion());
        updatedCompany.setListedRegion(null);
      }
      if (!Objects.equal(updatedCompany.getTicker(), newCompany.getTicker())) {
        changedInfo.put(ChangedInfoKeys.companyTicker(), updatedCompany.getTicker());
        updatedCompany.setTicker(null);
      }
    }

    if (!changedInfo.isEmpty()) {
      supplierInfoChangedDto.setChanged(true);
      supplierInfoChangedDto.setChangedInfo(changedInfo);
    }

    return supplierInfoChangedDto;
  }