File indexing completed on 2024-05-12 05:22:29

0001 /*
0002  * SPDX-FileCopyrightText: 2021 Daniel Vrátil <dvratil@kde.org>
0003  * SPDX-FileCopyrightText: 2022 Claudio Cambra <claudio.cambra@kde.org>
0004  *
0005  * SPDX-License-Identifier: LGPL-2.1-only
0006  * SPDX-License-Identifier: LGPL-3.0-only
0007  * SPDX-License-Identifier: LicenseRef-KDE-Accepted-LGPL
0008  */
0009 
0010 #include "person.h"
0011 
0012 #include "debug.h"
0013 
0014 #include "address.h"
0015 #include "agerangetype.h"
0016 #include "biography.h"
0017 #include "birthday.h"
0018 #include "braggingrights.h"
0019 #include "calendarurl.h"
0020 #include "clientdata.h"
0021 #include "coverphoto.h"
0022 #include "emailaddress.h"
0023 #include "event.h"
0024 #include "externalid.h"
0025 #include "fileas.h"
0026 #include "gender.h"
0027 #include "imclient.h"
0028 #include "interest.h"
0029 #include "location.h"
0030 #include "membership.h"
0031 #include "misckeyword.h"
0032 #include "name.h"
0033 #include "nickname.h"
0034 #include "occupation.h"
0035 #include "organization.h"
0036 #include "personlocale.h"
0037 #include "personmetadata.h"
0038 #include "phonenumber.h"
0039 #include "photo.h"
0040 #include "relation.h"
0041 #include "relationshipinterest.h"
0042 #include "relationshipstatus.h"
0043 #include "residence.h"
0044 #include "sipaddress.h"
0045 #include "skill.h"
0046 #include "tagline.h"
0047 #include "url.h"
0048 #include "userdefined.h"
0049 
0050 #include <algorithm>
0051 #include <QJsonObject>
0052 #include <QJsonArray>
0053 
0054 #include <KContacts/Addressee>
0055 
0056 namespace KGAPI2::People
0057 {
0058 class Person::Private
0059 {
0060 public:
0061     explicit Private() = default;
0062     Private(const Private &) = default;
0063     Private(Private &&) noexcept = delete;
0064     Private &operator=(const Private &) = delete;
0065     Private &operator=(Private &&) noexcept = delete;
0066     ~Private() = default;
0067 
0068     bool operator==(const Private &other) const
0069     {
0070         return nicknames == other.nicknames &&
0071             emailAddresses == other.emailAddresses &&
0072             clientData == other.clientData &&
0073             braggingRights == other.braggingRights &&
0074             relationshipStatuses == other.relationshipStatuses &&
0075             birthdays == other.birthdays &&
0076             relations == other.relations &&
0077             locales == other.locales &&
0078             locations == other.locations &&
0079             externalIds == other.externalIds &&
0080             ageRanges == other.ageRanges &&
0081             taglines == other.taglines &&
0082             userDefined == other.userDefined &&
0083             biographies == other.biographies &&
0084             sipAddresses == other.sipAddresses &&
0085             memberships == other.memberships &&
0086             skills == other.skills &&
0087             residences == other.residences &&
0088             names == other.names &&
0089             calendarUrls == other.calendarUrls &&
0090             coverPhotos == other.coverPhotos &&
0091             addresses == other.addresses &&
0092             etag == other.etag &&
0093             phoneNumbers == other.phoneNumbers &&
0094             imClients == other.imClients &&
0095             events == other.events &&
0096             photos == other.photos &&
0097             occupations == other.occupations &&
0098             miscKeywords == other.miscKeywords &&
0099             relationshipInterests == other.relationshipInterests &&
0100             resourceName == other.resourceName &&
0101             interests == other.interests &&
0102             organizations == other.organizations &&
0103             urls == other.urls &&
0104             genders == other.genders &&
0105             fileAses == other.fileAses &&
0106             ageRange == other.ageRange &&
0107             metadata == other.metadata;
0108     }
0109 
0110     bool operator!=(const Private &other) const
0111     {
0112         return !(*this == other);
0113     }
0114 
0115     KContacts::Addressee toKContactsAddressee()
0116     {
0117         KContacts::Addressee addressee;
0118 
0119         setKContactAddresseeNameFields(addressee);
0120         setKContactAddresseeNicknameFields(addressee);
0121         setKContactAddresseeBirthdayFields(addressee);
0122         setKContactAddresseeEmailFields(addressee);
0123         setKContactAddresseePhoneFields(addressee);
0124         setKContactAddresseeUrlFields(addressee);
0125         setKContactAddresseeOrganizationFields(addressee);
0126         setKContactAddresseeProfessionFields(addressee);
0127         setKContactAddresseePhoto(addressee);
0128 
0129         return addressee;
0130     }
0131 
0132     void setFromKContactsAddressee(const KContacts::Addressee &addressee)
0133     {
0134         if (!addressee.familyName().isEmpty() ||
0135             !addressee.givenName().isEmpty() ||
0136             !addressee.prefix().isEmpty() ||
0137             !addressee.suffix().isEmpty()) {
0138 
0139             names = {Name::fromKContactsAddressee(addressee)};
0140         }
0141 
0142         const auto addresseeNickName = addressee.nickName();
0143         if (!addresseeNickName.isEmpty()) {
0144             Nickname nickname;
0145             nickname.setValue(addresseeNickName);
0146             nicknames = {nickname};
0147         }
0148 
0149         const auto addresseeBirthday = addressee.birthday();
0150         if (addresseeBirthday.isValid()) {
0151             Birthday birthday;
0152             birthday.setDate(addresseeBirthday.date());
0153             birthdays = {birthday};
0154         }
0155 
0156         const auto addresseeEmailList = addressee.emailList();
0157         if (!addresseeEmailList.isEmpty()) {
0158             emailAddresses = EmailAddress::fromKContactsEmailList(addresseeEmailList);
0159         }
0160 
0161         const auto addresseePhoneNumbers = addressee.phoneNumbers();
0162         if (!addresseePhoneNumbers.isEmpty()) {
0163             phoneNumbers = PhoneNumber::fromKContactsPhoneNumberList(addressee.phoneNumbers());
0164         }
0165 
0166         const auto addresseeProfession = addressee.profession();
0167         if (!addresseeProfession.isEmpty()) {
0168             Occupation occupation;
0169             occupation.setValue(addresseeProfession);
0170             occupations = {occupation};
0171         }
0172 
0173         const auto addresseeOrganization = addressee.organization();
0174         const auto addresseeDepartment = addressee.department();
0175         if (!addresseeOrganization.isEmpty() || !addresseeDepartment.isEmpty()) {
0176             Organization organization;
0177             organization.setName(addresseeOrganization);
0178             organization.setDepartment(addresseeDepartment);
0179             organizations = {organization};
0180         }
0181 
0182         const auto addresseePhoto = addressee.photo();
0183         if (!addresseePhoto.isEmpty()) {
0184             Photo photo;
0185             photo.setUrl(addressee.photo().url());
0186             photos = {photo};
0187         }
0188 
0189         const auto blogFeed = addressee.blogFeed();
0190         if (!blogFeed.isEmpty()) {
0191             Url url;
0192             url.setValue(blogFeed.toString());
0193             url.setType(QStringLiteral("blog"));
0194             urls.append(url);
0195         }
0196 
0197         const auto addresseeUrls = addressee.extraUrlList();
0198         for (const auto &addresseeUrl : addresseeUrls) {
0199             Url url;
0200             url.setValue(addresseeUrl.toString());
0201 
0202             switch (addresseeUrl.type()) {
0203             case KContacts::ResourceLocatorUrl::Home:
0204                 url.setType(QStringLiteral("home"));
0205                 break;
0206             case KContacts::ResourceLocatorUrl::Profile:
0207                 url.setType(QStringLiteral("profile"));
0208                 break;
0209             case KContacts::ResourceLocatorUrl::Work:
0210                 url.setType(QStringLiteral("work"));
0211                 break;
0212             case KContacts::ResourceLocatorUrl::Ftp:
0213                 url.setType(QStringLiteral("ftp"));
0214                 break;
0215             case KContacts::ResourceLocatorUrl::AppInstallPage:
0216                 url.setType(QStringLiteral("appInstallPage"));
0217                 break;
0218             case KContacts::ResourceLocatorUrl::Reservation:
0219                 url.setType(QStringLiteral("reservations"));
0220                 break;
0221             default:
0222                 url.setType(QStringLiteral("other"));
0223             }
0224 
0225             urls.append(url);
0226         }
0227 
0228         const auto addressessCalendarUrls = addressee.calendarUrlList();
0229         for (const auto &calendarUrl : addressessCalendarUrls) {
0230             CalendarUrl gCalendarUrl;
0231             if (calendarUrl.type() == KContacts::CalendarUrl::FBUrl) {
0232                 gCalendarUrl.setType(QStringLiteral("freeBusy"));
0233             } else if (calendarUrl.type() == KContacts::CalendarUrl::CALUri) {
0234                 gCalendarUrl.setType(QStringLiteral("CALUri"));
0235             } else if (calendarUrl.type() == KContacts::CalendarUrl::CALADRUri) {
0236                 gCalendarUrl.setType(QStringLiteral("CALADRUri"));
0237             } else {
0238                 gCalendarUrl.setType(QStringLiteral("other"));
0239             }
0240             gCalendarUrl.setUrl(calendarUrl.url().toString());
0241             calendarUrls.append(gCalendarUrl);
0242         }
0243     }
0244 
0245     QList<Nickname> nicknames{};
0246     QList<EmailAddress> emailAddresses{};
0247     QList<ClientData> clientData{};
0248     QList<BraggingRights> braggingRights{};
0249     QList<RelationshipStatus> relationshipStatuses{};
0250     QList<Birthday> birthdays{};
0251     QList<Relation> relations{};
0252     QList<PersonLocale> locales{};
0253     QList<Location> locations{};
0254     QList<ExternalId> externalIds{};
0255     QList<AgeRangeType> ageRanges{};
0256     QList<Tagline> taglines{};
0257     QList<UserDefined> userDefined{};
0258     QList<Biography> biographies{};
0259     QList<SipAddress> sipAddresses{};
0260     QList<Membership> memberships{};
0261     QList<Skill> skills{};
0262     QList<Residence> residences{};
0263     QList<Name> names{};
0264     QList<CalendarUrl> calendarUrls{};
0265     QList<CoverPhoto> coverPhotos{};
0266     QList<Address> addresses{};
0267     QString etag{};
0268     QList<PhoneNumber> phoneNumbers{};
0269     QList<ImClient> imClients{};
0270     QList<Event> events{};
0271     QList<Photo> photos{};
0272     QList<Occupation> occupations{};
0273     QList<MiscKeyword> miscKeywords{};
0274     QList<RelationshipInterest> relationshipInterests{};
0275     QString resourceName{};
0276     QList<Interest> interests{};
0277     QList<Organization> organizations{};
0278     QList<Url> urls{};
0279     QList<Gender> genders{};
0280     QList<FileAs> fileAses{};
0281     Person::AgeRange ageRange{};
0282     PersonMetadata metadata{};
0283 
0284 private:
0285     void setKContactAddresseeNameFields(KContacts::Addressee &addressee)
0286     {
0287         if (names.isEmpty()) {
0288             return;
0289         }
0290 
0291         const auto nameToUse = names.first();
0292         nameToUse.applyToKContactsAddressee(addressee);
0293     }
0294 
0295     void setKContactAddresseeNicknameFields(KContacts::Addressee &addressee)
0296     {
0297         if(nicknames.isEmpty()) {
0298             addressee.setNickName(QString());
0299             return;
0300         }
0301 
0302         const auto nicknameToUse = nicknames.first();
0303         addressee.setNickName(nicknameToUse.value());
0304     }
0305 
0306     void setKContactAddresseeBirthdayFields(KContacts::Addressee &addressee)
0307     {
0308         if(birthdays.isEmpty()) {
0309             addressee.setBirthday(QDate());
0310             return;
0311         }
0312 
0313         const auto birthdayToUse = birthdays.first();
0314         addressee.setBirthday(birthdayToUse.date());
0315     }
0316 
0317     void setKContactAddresseeEmailFields(KContacts::Addressee &addressee)
0318     {
0319         KContacts::Email::List convertedEmails;
0320 
0321         std::transform(emailAddresses.cbegin(),
0322                        emailAddresses.cend(),
0323                        std::back_inserter(convertedEmails),
0324                        [](const EmailAddress &emailAddress) {
0325                            return emailAddress.toKContactsEmail();
0326                        });
0327 
0328         addressee.setEmailList(convertedEmails);
0329     }
0330 
0331     void setKContactAddresseePhoneFields(KContacts::Addressee &addressee)
0332     {
0333         KContacts::PhoneNumber::List convertedPhoneNumbers;
0334 
0335         std::transform(phoneNumbers.cbegin(),
0336                        phoneNumbers.cend(),
0337                        std::back_inserter(convertedPhoneNumbers),
0338                        [](const People::PhoneNumber &phoneNumber) {
0339                            return phoneNumber.toKContactsPhoneNumber();
0340                        });
0341 
0342         addressee.setPhoneNumbers(convertedPhoneNumbers);
0343     }
0344 
0345     void setKContactAddresseeOrganizationFields(KContacts::Addressee &addressee)
0346     {
0347         if (organizations.isEmpty()) {
0348             addressee.setOrganization(QString());
0349             addressee.setDepartment(QString());
0350             return;
0351         }
0352 
0353         const auto organizationToUse = organizations.first();
0354         addressee.setOrganization(organizationToUse.name());
0355         addressee.setDepartment(organizationToUse.department());
0356     }
0357 
0358     void setKContactAddresseeProfessionFields(KContacts::Addressee &addressee)
0359     {
0360         if (occupations.isEmpty()) {
0361             addressee.setProfession(QString());
0362             return;
0363         }
0364 
0365         const auto occupationToUse = occupations.first();
0366         addressee.setProfession(occupationToUse.value());
0367     }
0368 
0369     void setKContactAddresseePhoto(KContacts::Addressee &addressee)
0370     {
0371         if (photos.isEmpty()) {
0372             addressee.setPhoto({});
0373             return;
0374         }
0375 
0376         const auto photoToUse = photos.first();
0377         KContacts::Picture picture(photoToUse.url());
0378         addressee.setPhoto(picture);
0379     }
0380 
0381     void setKContactAddresseeUrlFields(KContacts::Addressee &addressee)
0382     {
0383         if (urls.isEmpty()) {
0384             addressee.setBlogFeed({});
0385             addressee.setUrl(QUrl{});
0386             addressee.setExtraUrlList({});
0387         } else {
0388             for (const auto &url : std::as_const(urls)) {
0389                 if (url.type() == QLatin1StringView("blog")) {
0390                     addressee.setBlogFeed(QUrl(url.value()));
0391                 } else {
0392                     KContacts::ResourceLocatorUrl::Type type;
0393 
0394                     if (url.type() == QLatin1StringView("home") || url.type() == QLatin1StringView("homePage")) {
0395                         type = KContacts::ResourceLocatorUrl::Home;
0396                     } else if (url.type() == QLatin1StringView("profile")) {
0397                         type = KContacts::ResourceLocatorUrl::Profile;
0398                     } else if (url.type() == QLatin1StringView("work")) {
0399                         type = KContacts::ResourceLocatorUrl::Work;
0400                     } else if (url.type() == QLatin1StringView("ftp")) {
0401                         type = KContacts::ResourceLocatorUrl::Ftp;
0402                     } else if (url.type() == QLatin1StringView("appInstallPage")) {
0403                         type = KContacts::ResourceLocatorUrl::AppInstallPage;
0404                     } else if (url.type() == QLatin1StringView("reservations")) {
0405                         type = KContacts::ResourceLocatorUrl::Reservation;
0406                     } else {
0407                         type = KContacts::ResourceLocatorUrl::Other;
0408                     }
0409 
0410                     KContacts::ResourceLocatorUrl resourceUrl;
0411                     resourceUrl.setUrl(QUrl(url.value()));
0412                     resourceUrl.setType(type);
0413                     addressee.insertExtraUrl(resourceUrl);
0414                 }
0415             }
0416         }
0417 
0418 
0419         for (const auto &calendarUrl : std::as_const(calendarUrls)) {
0420             KContacts::CalendarUrl kCalendarUrl;
0421             if (calendarUrl.type() == QLatin1StringView("freeBusy")) {
0422                 kCalendarUrl.setType(KContacts::CalendarUrl::FBUrl);
0423             } else if (calendarUrl.type() == QLatin1StringView("CALUri")) {
0424                 kCalendarUrl.setType(KContacts::CalendarUrl::CALUri);
0425             } else if (calendarUrl.type() == QLatin1StringView("CALADRUri")) {
0426                 kCalendarUrl.setType(KContacts::CalendarUrl::CALADRUri);
0427             } else {
0428                 kCalendarUrl.setType(KContacts::CalendarUrl::Unknown);
0429             }
0430             kCalendarUrl.setUrl(QUrl(calendarUrl.url()));
0431             addressee.insertCalendarUrl(kCalendarUrl);
0432         }
0433     }
0434 };
0435 
0436 Person::Person()
0437     : KGAPI2::Object()
0438     , d(new Private)
0439 {
0440 }
0441 
0442 Person::~Person() = default;
0443 
0444 QList<Nickname> Person::nicknames() const
0445 {
0446     return d->nicknames;
0447 }
0448 
0449 void Person::setNicknames(const QList<Nickname> &value)
0450 {
0451     d->nicknames = value;
0452 }
0453 
0454 void Person::addNickname(const Nickname &value)
0455 {
0456     d->nicknames.push_back(value);
0457 }
0458 
0459 void Person::removeNickname(const Nickname &value)
0460 {
0461     d->nicknames.removeOne(value);
0462 }
0463 
0464 void Person::clearNicknames()
0465 {
0466     d->nicknames.clear();
0467 }
0468 
0469 QList<EmailAddress> Person::emailAddresses() const
0470 {
0471     return d->emailAddresses;
0472 }
0473 
0474 void Person::setEmailAddresses(const QList<EmailAddress> &value)
0475 {
0476     d->emailAddresses = value;
0477 }
0478 
0479 void Person::addEmailAddress(const EmailAddress &value)
0480 {
0481     d->emailAddresses.push_back(value);
0482 }
0483 
0484 void Person::removeEmailAddress(const EmailAddress &value)
0485 {
0486     d->emailAddresses.removeOne(value);
0487 }
0488 
0489 void Person::clearEmailAddresses()
0490 {
0491     d->emailAddresses.clear();
0492 }
0493 
0494 QList<ClientData> Person::clientData() const
0495 {
0496     return d->clientData;
0497 }
0498 
0499 void Person::setClientData(const QList<ClientData> &value)
0500 {
0501     d->clientData = value;
0502 }
0503 
0504 void Person::addClientData(const ClientData &value)
0505 {
0506     d->clientData.push_back(value);
0507 }
0508 
0509 void Person::removeClientData(const ClientData &value)
0510 {
0511     d->clientData.removeOne(value);
0512 }
0513 
0514 void Person::clearClientData()
0515 {
0516     d->clientData.clear();
0517 }
0518 
0519 QList<BraggingRights> Person::braggingRights() const
0520 {
0521     return d->braggingRights;
0522 }
0523 
0524 void Person::setBraggingRights(const QList<BraggingRights> &value)
0525 {
0526     d->braggingRights = value;
0527 }
0528 
0529 void Person::addBraggingRights(const BraggingRights &value)
0530 {
0531     d->braggingRights.push_back(value);
0532 }
0533 
0534 void Person::removeBraggingRights(const BraggingRights &value)
0535 {
0536     d->braggingRights.removeOne(value);
0537 }
0538 
0539 void Person::clearBraggingRights()
0540 {
0541     d->braggingRights.clear();
0542 }
0543 
0544 QList<RelationshipStatus> Person::relationshipStatuses() const
0545 {
0546     return d->relationshipStatuses;
0547 }
0548 QList<Birthday> Person::birthdays() const
0549 {
0550     return d->birthdays;
0551 }
0552 
0553 void Person::setBirthdays(const QList<Birthday> &value)
0554 {
0555     d->birthdays = value;
0556 }
0557 
0558 void Person::addBirthday(const Birthday &value)
0559 {
0560     d->birthdays.push_back(value);
0561 }
0562 
0563 void Person::removeBirthday(const Birthday &value)
0564 {
0565     d->birthdays.removeOne(value);
0566 }
0567 
0568 void Person::clearBirthdays()
0569 {
0570     d->birthdays.clear();
0571 }
0572 
0573 QList<Relation> Person::relations() const
0574 {
0575     return d->relations;
0576 }
0577 
0578 void Person::setRelations(const QList<Relation> &value)
0579 {
0580     d->relations = value;
0581 }
0582 
0583 void Person::addRelation(const Relation &value)
0584 {
0585     d->relations.push_back(value);
0586 }
0587 
0588 void Person::removeRelation(const Relation &value)
0589 {
0590     d->relations.removeOne(value);
0591 }
0592 
0593 void Person::clearRelations()
0594 {
0595     d->relations.clear();
0596 }
0597 
0598 QList<PersonLocale> Person::locales() const
0599 {
0600     return d->locales;
0601 }
0602 
0603 void Person::setLocales(const QList<PersonLocale> &value)
0604 {
0605     d->locales = value;
0606 }
0607 
0608 void Person::addPersonLocale(const PersonLocale &value)
0609 {
0610     d->locales.push_back(value);
0611 }
0612 
0613 void Person::removePersonLocale(const PersonLocale &value)
0614 {
0615     d->locales.removeOne(value);
0616 }
0617 
0618 void Person::clearLocales()
0619 {
0620     d->locales.clear();
0621 }
0622 
0623 QList<Location> Person::locations() const
0624 {
0625     return d->locations;
0626 }
0627 
0628 void Person::setLocations(const QList<Location> &value)
0629 {
0630     d->locations = value;
0631 }
0632 
0633 void Person::addLocation(const Location &value)
0634 {
0635     d->locations.push_back(value);
0636 }
0637 
0638 void Person::removeLocation(const Location &value)
0639 {
0640     d->locations.removeOne(value);
0641 }
0642 
0643 void Person::clearLocations()
0644 {
0645     d->locations.clear();
0646 }
0647 
0648 QList<ExternalId> Person::externalIds() const
0649 {
0650     return d->externalIds;
0651 }
0652 
0653 void Person::setExternalIds(const QList<ExternalId> &value)
0654 {
0655     d->externalIds = value;
0656 }
0657 
0658 void Person::addExternalId(const ExternalId &value)
0659 {
0660     d->externalIds.push_back(value);
0661 }
0662 
0663 void Person::removeExternalId(const ExternalId &value)
0664 {
0665     d->externalIds.removeOne(value);
0666 }
0667 
0668 void Person::clearExternalIds()
0669 {
0670     d->externalIds.clear();
0671 }
0672 
0673 QList<AgeRangeType> Person::ageRanges() const
0674 {
0675     return d->ageRanges;
0676 }
0677 QList<Tagline> Person::taglines() const
0678 {
0679     return d->taglines;
0680 }
0681 QList<UserDefined> Person::userDefined() const
0682 {
0683     return d->userDefined;
0684 }
0685 
0686 void Person::setUserDefined(const QList<UserDefined> &value)
0687 {
0688     d->userDefined = value;
0689 }
0690 
0691 void Person::addUserDefined(const UserDefined &value)
0692 {
0693     d->userDefined.push_back(value);
0694 }
0695 
0696 void Person::removeUserDefined(const UserDefined &value)
0697 {
0698     d->userDefined.removeOne(value);
0699 }
0700 
0701 void Person::clearUserDefined()
0702 {
0703     d->userDefined.clear();
0704 }
0705 
0706 QList<Biography> Person::biographies() const
0707 {
0708     return d->biographies;
0709 }
0710 
0711 void Person::setBiographies(const QList<Biography> &value)
0712 {
0713     d->biographies = value;
0714 }
0715 
0716 void Person::addBiography(const Biography &value)
0717 {
0718     d->biographies.push_back(value);
0719 }
0720 
0721 void Person::removeBiography(const Biography &value)
0722 {
0723     d->biographies.removeOne(value);
0724 }
0725 
0726 void Person::clearBiographies()
0727 {
0728     d->biographies.clear();
0729 }
0730 
0731 QList<SipAddress> Person::sipAddresses() const
0732 {
0733     return d->sipAddresses;
0734 }
0735 
0736 void Person::setSipAddresses(const QList<SipAddress> &value)
0737 {
0738     d->sipAddresses = value;
0739 }
0740 
0741 void Person::addSipAddress(const SipAddress &value)
0742 {
0743     d->sipAddresses.push_back(value);
0744 }
0745 
0746 void Person::removeSipAddress(const SipAddress &value)
0747 {
0748     d->sipAddresses.removeOne(value);
0749 }
0750 
0751 void Person::clearSipAddresses()
0752 {
0753     d->sipAddresses.clear();
0754 }
0755 
0756 QList<Membership> Person::memberships() const
0757 {
0758     return d->memberships;
0759 }
0760 
0761 void Person::setMemberships(const QList<Membership> &value)
0762 {
0763     d->memberships = value;
0764 }
0765 
0766 void Person::addMembership(const Membership &value)
0767 {
0768     d->memberships.push_back(value);
0769 }
0770 
0771 void Person::removeMembership(const Membership &value)
0772 {
0773     d->memberships.removeOne(value);
0774 }
0775 
0776 void Person::clearMemberships()
0777 {
0778     d->memberships.clear();
0779 }
0780 
0781 QList<Skill> Person::skills() const
0782 {
0783     return d->skills;
0784 }
0785 
0786 void Person::setSkills(const QList<Skill> &value)
0787 {
0788     d->skills = value;
0789 }
0790 
0791 void Person::addSkill(const Skill &value)
0792 {
0793     d->skills.push_back(value);
0794 }
0795 
0796 void Person::removeSkill(const Skill &value)
0797 {
0798     d->skills.removeOne(value);
0799 }
0800 
0801 void Person::clearSkills()
0802 {
0803     d->skills.clear();
0804 }
0805 
0806 QList<Residence> Person::residences() const
0807 {
0808     return d->residences;
0809 }
0810 
0811 void Person::setResidences(const QList<Residence> &value)
0812 {
0813     d->residences = value;
0814 }
0815 
0816 void Person::addResidence(const Residence &value)
0817 {
0818     d->residences.push_back(value);
0819 }
0820 
0821 void Person::removeResidence(const Residence &value)
0822 {
0823     d->residences.removeOne(value);
0824 }
0825 
0826 void Person::clearResidences()
0827 {
0828     d->residences.clear();
0829 }
0830 
0831 QList<Name> Person::names() const
0832 {
0833     return d->names;
0834 }
0835 
0836 void Person::setNames(const QList<Name> &value)
0837 {
0838     d->names = value;
0839 }
0840 
0841 void Person::addName(const Name &value)
0842 {
0843     d->names.push_back(value);
0844 }
0845 
0846 void Person::removeName(const Name &value)
0847 {
0848     d->names.removeOne(value);
0849 }
0850 
0851 void Person::clearNames()
0852 {
0853     d->names.clear();
0854 }
0855 
0856 QList<CalendarUrl> Person::calendarUrls() const
0857 {
0858     return d->calendarUrls;
0859 }
0860 
0861 void Person::setCalendarUrls(const QList<CalendarUrl> &value)
0862 {
0863     d->calendarUrls = value;
0864 }
0865 
0866 void Person::addCalendarUrl(const CalendarUrl &value)
0867 {
0868     d->calendarUrls.push_back(value);
0869 }
0870 
0871 void Person::removeCalendarUrl(const CalendarUrl &value)
0872 {
0873     d->calendarUrls.removeOne(value);
0874 }
0875 
0876 void Person::clearCalendarUrls()
0877 {
0878     d->calendarUrls.clear();
0879 }
0880 
0881 QList<CoverPhoto> Person::coverPhotos() const
0882 {
0883     return d->coverPhotos;
0884 }
0885 QList<Address> Person::addresses() const
0886 {
0887     return d->addresses;
0888 }
0889 
0890 void Person::setAddresses(const QList<Address> &value)
0891 {
0892     d->addresses = value;
0893 }
0894 
0895 void Person::addAddress(const Address &value)
0896 {
0897     d->addresses.push_back(value);
0898 }
0899 
0900 void Person::removeAddress(const Address &value)
0901 {
0902     d->addresses.removeOne(value);
0903 }
0904 
0905 void Person::clearAddresses()
0906 {
0907     d->addresses.clear();
0908 }
0909 
0910 QString Person::etag() const
0911 {
0912     return d->etag;
0913 }
0914 
0915 void Person::setEtag(const QString &value)
0916 {
0917     d->etag = value;
0918 }
0919 QList<PhoneNumber> Person::phoneNumbers() const
0920 {
0921     return d->phoneNumbers;
0922 }
0923 
0924 void Person::setPhoneNumbers(const QList<PhoneNumber> &value)
0925 {
0926     d->phoneNumbers = value;
0927 }
0928 
0929 void Person::addPhoneNumber(const PhoneNumber &value)
0930 {
0931     d->phoneNumbers.push_back(value);
0932 }
0933 
0934 void Person::removePhoneNumber(const PhoneNumber &value)
0935 {
0936     d->phoneNumbers.removeOne(value);
0937 }
0938 
0939 void Person::clearPhoneNumbers()
0940 {
0941     d->phoneNumbers.clear();
0942 }
0943 
0944 QList<ImClient> Person::imClients() const
0945 {
0946     return d->imClients;
0947 }
0948 
0949 void Person::setImClients(const QList<ImClient> &value)
0950 {
0951     d->imClients = value;
0952 }
0953 
0954 void Person::addImClient(const ImClient &value)
0955 {
0956     d->imClients.push_back(value);
0957 }
0958 
0959 void Person::removeImClient(const ImClient &value)
0960 {
0961     d->imClients.removeOne(value);
0962 }
0963 
0964 void Person::clearImClients()
0965 {
0966     d->imClients.clear();
0967 }
0968 
0969 QList<Event> Person::events() const
0970 {
0971     return d->events;
0972 }
0973 
0974 void Person::setEvents(const QList<Event> &value)
0975 {
0976     d->events = value;
0977 }
0978 
0979 void Person::addEvent(const Event &value)
0980 {
0981     d->events.push_back(value);
0982 }
0983 
0984 void Person::removeEvent(const Event &value)
0985 {
0986     d->events.removeOne(value);
0987 }
0988 
0989 void Person::clearEvents()
0990 {
0991     d->events.clear();
0992 }
0993 
0994 QList<Photo> Person::photos() const
0995 {
0996     return d->photos;
0997 }
0998 QList<Occupation> Person::occupations() const
0999 {
1000     return d->occupations;
1001 }
1002 
1003 void Person::setOccupations(const QList<Occupation> &value)
1004 {
1005     d->occupations = value;
1006 }
1007 
1008 void Person::addOccupation(const Occupation &value)
1009 {
1010     d->occupations.push_back(value);
1011 }
1012 
1013 void Person::removeOccupation(const Occupation &value)
1014 {
1015     d->occupations.removeOne(value);
1016 }
1017 
1018 void Person::clearOccupations()
1019 {
1020     d->occupations.clear();
1021 }
1022 
1023 QList<MiscKeyword> Person::miscKeywords() const
1024 {
1025     return d->miscKeywords;
1026 }
1027 
1028 void Person::setMiscKeywords(const QList<MiscKeyword> &value)
1029 {
1030     d->miscKeywords = value;
1031 }
1032 
1033 void Person::addMiscKeyword(const MiscKeyword &value)
1034 {
1035     d->miscKeywords.push_back(value);
1036 }
1037 
1038 void Person::removeMiscKeyword(const MiscKeyword &value)
1039 {
1040     d->miscKeywords.removeOne(value);
1041 }
1042 
1043 void Person::clearMiscKeywords()
1044 {
1045     d->miscKeywords.clear();
1046 }
1047 
1048 QList<RelationshipInterest> Person::relationshipInterests() const
1049 {
1050     return d->relationshipInterests;
1051 }
1052 QString Person::resourceName() const
1053 {
1054     return d->resourceName;
1055 }
1056 
1057 void Person::setResourceName(const QString &value)
1058 {
1059     d->resourceName = value;
1060 }
1061 QList<Interest> Person::interests() const
1062 {
1063     return d->interests;
1064 }
1065 
1066 void Person::setInterests(const QList<Interest> &value)
1067 {
1068     d->interests = value;
1069 }
1070 
1071 void Person::addInterest(const Interest &value)
1072 {
1073     d->interests.push_back(value);
1074 }
1075 
1076 void Person::removeInterest(const Interest &value)
1077 {
1078     d->interests.removeOne(value);
1079 }
1080 
1081 void Person::clearInterests()
1082 {
1083     d->interests.clear();
1084 }
1085 
1086 QList<Organization> Person::organizations() const
1087 {
1088     return d->organizations;
1089 }
1090 
1091 void Person::setOrganizations(const QList<Organization> &value)
1092 {
1093     d->organizations = value;
1094 }
1095 
1096 void Person::addOrganization(const Organization &value)
1097 {
1098     d->organizations.push_back(value);
1099 }
1100 
1101 void Person::removeOrganization(const Organization &value)
1102 {
1103     d->organizations.removeOne(value);
1104 }
1105 
1106 void Person::clearOrganizations()
1107 {
1108     d->organizations.clear();
1109 }
1110 
1111 QList<Url> Person::urls() const
1112 {
1113     return d->urls;
1114 }
1115 
1116 void Person::setUrls(const QList<Url> &value)
1117 {
1118     d->urls = value;
1119 }
1120 
1121 void Person::addUrl(const Url &value)
1122 {
1123     d->urls.push_back(value);
1124 }
1125 
1126 void Person::removeUrl(const Url &value)
1127 {
1128     d->urls.removeOne(value);
1129 }
1130 
1131 void Person::clearUrls()
1132 {
1133     d->urls.clear();
1134 }
1135 
1136 QList<Gender> Person::genders() const
1137 {
1138     return d->genders;
1139 }
1140 
1141 void Person::setGenders(const QList<Gender> &value)
1142 {
1143     d->genders = value;
1144 }
1145 
1146 void Person::addGender(const Gender &value)
1147 {
1148     d->genders.push_back(value);
1149 }
1150 
1151 void Person::removeGender(const Gender &value)
1152 {
1153     d->genders.removeOne(value);
1154 }
1155 
1156 void Person::clearGenders()
1157 {
1158     d->genders.clear();
1159 }
1160 
1161 QList<FileAs> Person::fileAses() const
1162 {
1163     return d->fileAses;
1164 }
1165 
1166 void Person::setFileAses(const QList<FileAs> &value)
1167 {
1168     d->fileAses = value;
1169 }
1170 
1171 void Person::addFileAs(const FileAs &value)
1172 {
1173     d->fileAses.push_back(value);
1174 }
1175 
1176 void Person::removeFileAs(const FileAs &value)
1177 {
1178     d->fileAses.removeOne(value);
1179 }
1180 
1181 void Person::clearFileAses()
1182 {
1183     d->fileAses.clear();
1184 }
1185 
1186 Person::Person::AgeRange Person::ageRange() const
1187 {
1188     return d->ageRange;
1189 }
1190 PersonMetadata Person::metadata() const
1191 {
1192     return d->metadata;
1193 }
1194 
1195 PersonPtr Person::fromJSON(const QJsonObject &obj)
1196 {
1197     auto person = new Person;
1198 
1199     if (!obj.isEmpty()) {
1200         person->d->resourceName = obj.value(QStringLiteral("resourceName")).toString();
1201         person->d->etag = obj.value(QStringLiteral("etag")).toString();
1202 
1203         const auto metadata = obj.value(QStringLiteral("metadata")).toObject();
1204         person->d->metadata = PersonMetadata::fromJSON(metadata);
1205 
1206         const auto addresses = obj.value(QStringLiteral("addresses")).toArray();
1207         person->d->addresses = Address::fromJSONArray(addresses);
1208 
1209         const auto ageRanges = obj.value(QStringLiteral("ageRanges")).toArray();
1210         person->d->ageRanges = AgeRangeType::fromJSONArray(ageRanges);
1211 
1212         const auto biographies = obj.value(QStringLiteral("biographies")).toArray();
1213         person->d->biographies = Biography::fromJSONArray(biographies);
1214 
1215         const auto birthdays = obj.value(QStringLiteral("birthdays")).toArray();
1216         person->d->birthdays = Birthday::fromJSONArray(birthdays);
1217 
1218         // Bragging rights are deprecated and return nothing. Pass
1219 
1220         const auto calendarUrls = obj.value(QStringLiteral("calendarUrls")).toArray();
1221         person->d->calendarUrls = CalendarUrl::fromJSONArray(calendarUrls);
1222 
1223         const auto clientData = obj.value(QStringLiteral("clientData")).toArray();
1224         person->d->clientData = ClientData::fromJSONArray(clientData);
1225 
1226         const auto coverPhotos = obj.value(QStringLiteral("coverPhotos")).toArray();
1227         person->d->coverPhotos = CoverPhoto::fromJSONArray(coverPhotos);
1228 
1229         const auto emailAddresses = obj.value(QStringLiteral("emailAddresses")).toArray();
1230         person->d->emailAddresses = EmailAddress::fromJSONArray(emailAddresses);
1231 
1232         const auto events = obj.value(QStringLiteral("events")).toArray();
1233         person->d->events = Event::fromJSONArray(events);
1234 
1235         const auto externalIds = obj.value(QStringLiteral("externalIds")).toArray();
1236         person->d->externalIds = ExternalId::fromJSONArray(externalIds);
1237 
1238         const auto fileAses = obj.value(QStringLiteral("fileAses")).toArray();
1239         person->d->fileAses = FileAs::fromJSONArray(fileAses);
1240 
1241         const auto genders = obj.value(QStringLiteral("genders")).toArray();
1242         person->d->genders = Gender::fromJSONArray(genders);
1243 
1244         const auto imClients = obj.value(QStringLiteral("imClients")).toArray();
1245         person->d->imClients = ImClient::fromJSONArray(imClients);
1246 
1247         const auto interests = obj.value(QStringLiteral("interests")).toArray();
1248         person->d->interests = Interest::fromJSONArray(interests);
1249 
1250         const auto locales = obj.value(QStringLiteral("locales")).toArray();
1251         person->d->locales = PersonLocale::fromJSONArray(locales);
1252 
1253         const auto locations = obj.value(QStringLiteral("locations")).toArray();
1254         person->d->locations = Location::fromJSONArray(locations);
1255 
1256         const auto memberships = obj.value(QStringLiteral("memberships")).toArray();
1257         person->d->memberships = Membership::fromJSONArray(memberships);
1258 
1259         const auto miscKeywords = obj.value(QStringLiteral("miscKeywords")).toArray();
1260         person->d->miscKeywords = MiscKeyword::fromJSONArray(miscKeywords);
1261 
1262         const auto names = obj.value(QStringLiteral("names")).toArray();
1263         person->d->names = Name::fromJSONArray(names);
1264 
1265         const auto nicknames = obj.value(QStringLiteral("nicknames")).toArray();
1266         person->d->nicknames = Nickname::fromJSONArray(nicknames);
1267 
1268         const auto occupations = obj.value(QStringLiteral("occupations")).toArray();
1269         person->d->occupations = Occupation::fromJSONArray(occupations);
1270 
1271         const auto organizations = obj.value(QStringLiteral("organizations")).toArray();
1272         person->d->organizations = Organization::fromJSONArray(organizations);
1273 
1274         const auto phoneNumbers = obj.value(QStringLiteral("phoneNumbers")).toArray();
1275         person->d->phoneNumbers = PhoneNumber::fromJSONArray(phoneNumbers);
1276 
1277         const auto photos = obj.value(QStringLiteral("photos")).toArray();
1278         person->d->photos = Photo::fromJSONArray(photos);
1279 
1280         const auto relations = obj.value(QStringLiteral("relations")).toArray();
1281         person->d->relations = Relation::fromJSONArray(relations);
1282 
1283         // relationshipInterest is deprecated, provides no data
1284         // relationshipStatus is also deprecated
1285         // residence is also deprecated
1286 
1287         const auto sipAddresses = obj.value(QStringLiteral("sipAddresses")).toArray();
1288         person->d->sipAddresses = SipAddress::fromJSONArray(sipAddresses);
1289 
1290         const auto skills = obj.value(QStringLiteral("skills")).toArray();
1291         person->d->skills = Skill::fromJSONArray(skills);
1292 
1293         // tagline is deprecated, provides no data
1294 
1295         const auto urls = obj.value(QStringLiteral("urls")).toArray();
1296         person->d->urls = Url::fromJSONArray(urls);
1297 
1298         const auto userDefined = obj.value(QStringLiteral("userDefined")).toArray();
1299         person->d->userDefined = UserDefined::fromJSONArray(userDefined);
1300     }
1301 
1302     return People::PersonPtr(person);
1303 }
1304 
1305 QJsonValue Person::toJSON() const
1306 {
1307     QJsonObject returnObject;
1308     returnObject.insert(QStringLiteral("resourceName"), d->resourceName);
1309     returnObject.insert(QStringLiteral("etag"), d->etag);
1310 
1311     returnObject.insert(QStringLiteral("metadata"), d->metadata.toJSON());
1312 
1313     QJsonArray addressesArray;
1314     for (const auto &address : std::as_const(d->addresses)) {
1315         addressesArray.append(address.toJSON());
1316     }
1317     if (!addressesArray.isEmpty()) {
1318         returnObject.insert(QStringLiteral("addresses"), addressesArray);
1319     }
1320 
1321     /* Output only field
1322     QJsonArray ageRangesArray;
1323     for (const auto &ageRange : d->ageRanges) {
1324         ageRangesArray.append(ageRange.toJSON());
1325     }
1326     if (!ageRangesArray.isEmpty()) {
1327         returnObject.insert(QStringLiteral("ageRanges"), ageRangesArray);
1328     }
1329     */
1330 
1331     QJsonArray biographiesArray;
1332     for (const auto &biography : std::as_const(d->biographies)) {
1333         biographiesArray.append(biography.toJSON());
1334     }
1335     if (!biographiesArray.isEmpty()) {
1336         returnObject.insert(QStringLiteral("biographies"), biographiesArray);
1337     }
1338 
1339     QJsonArray birthdaysArray;
1340     for (const auto &birthday : std::as_const(d->birthdays)) {
1341         birthdaysArray.append(birthday.toJSON());
1342     }
1343     if (!birthdaysArray.isEmpty()) {
1344         returnObject.insert(QStringLiteral("birthdays"), birthdaysArray);
1345     }
1346 
1347     QJsonArray calendarUrlsArray;
1348     for (const auto &calendarUrl : std::as_const(d->calendarUrls)) {
1349         calendarUrlsArray.append(calendarUrl.toJSON());
1350     }
1351     if (!calendarUrlsArray.isEmpty()) {
1352         returnObject.insert(QStringLiteral("calendarUrls"), calendarUrlsArray);
1353     }
1354 
1355     QJsonArray clientDataArray;
1356     for (const auto &clientData : std::as_const(d->clientData)) {
1357         clientDataArray.append(clientData.toJSON());
1358     }
1359     if (!clientDataArray.isEmpty()) {
1360         returnObject.insert(QStringLiteral("clientData"), clientDataArray);
1361     }
1362 
1363     /* Output only field
1364     QJsonArray coverPhotosArray;
1365     for (const auto &coverPhoto : d->coverPhotos) {
1366         coverPhotosArray.append(coverPhoto.toJSON());
1367     }
1368     if (!coverPhotosArray.isEmpty()) {
1369         returnObject.insert(QStringLiteral("coverPhotos"), coverPhotosArray);
1370     }
1371     */
1372 
1373     QJsonArray emailAddressesArray;
1374     for (const auto &emailAddress : std::as_const(d->emailAddresses)) {
1375         emailAddressesArray.append(emailAddress.toJSON());
1376     }
1377     if (!emailAddressesArray.isEmpty()) {
1378         returnObject.insert(QStringLiteral("emailAddresses"), emailAddressesArray);
1379     }
1380 
1381     QJsonArray eventsArray;
1382     for (const auto &event : std::as_const(d->events)) {
1383         eventsArray.append(event.toJSON());
1384     }
1385     if (!eventsArray.isEmpty()) {
1386         returnObject.insert(QStringLiteral("events"), eventsArray);
1387     }
1388 
1389     QJsonArray externalIdsArray;
1390     for (const auto &externalId : std::as_const(d->externalIds)) {
1391         externalIdsArray.append(externalId.toJSON());
1392     }
1393     if (!externalIdsArray.isEmpty()) {
1394         returnObject.insert(QStringLiteral("externalIds"), externalIdsArray);
1395     }
1396 
1397     QJsonArray fileAsesArray;
1398     for (const auto &fileAs : std::as_const(d->fileAses)) {
1399         fileAsesArray.append(fileAs.toJSON());
1400     }
1401     if (!fileAsesArray.isEmpty()) {
1402         returnObject.insert(QStringLiteral("fileAses"), fileAsesArray);
1403     }
1404 
1405     QJsonArray gendersArray;
1406     for (const auto &gender : std::as_const(d->genders)) {
1407         gendersArray.append(gender.toJSON());
1408     }
1409     if (!gendersArray.isEmpty()) {
1410         returnObject.insert(QStringLiteral("genders"), gendersArray);
1411     }
1412 
1413     QJsonArray imClientsArray;
1414     for (const auto &imClient : std::as_const(d->imClients)) {
1415         imClientsArray.append(imClient.toJSON());
1416     }
1417     if (!imClientsArray.isEmpty()) {
1418         returnObject.insert(QStringLiteral("imClients"), imClientsArray);
1419     }
1420 
1421     QJsonArray interestsArray;
1422     for (const auto &interest : std::as_const(d->interests)) {
1423         interestsArray.append(interest.toJSON());
1424     }
1425     if (!interestsArray.isEmpty()) {
1426         returnObject.insert(QStringLiteral("interests"), interestsArray);
1427     }
1428 
1429     QJsonArray localesArray;
1430     for (const auto &locale : std::as_const(d->locales)) {
1431         localesArray.append(locale.toJSON());
1432     }
1433     if (!localesArray.isEmpty()) {
1434         returnObject.insert(QStringLiteral("locales"), localesArray);
1435     }
1436 
1437     QJsonArray locationsArray;
1438     for (const auto &location : std::as_const(d->locations)) {
1439         locationsArray.append(location.toJSON());
1440     }
1441     if (!locationsArray.isEmpty()) {
1442         returnObject.insert(QStringLiteral("locations"), locationsArray);
1443     }
1444 
1445     QJsonArray membershipsArray;
1446     for (const auto &membership : std::as_const(d->memberships)) {
1447         membershipsArray.append(membership.toJSON());
1448     }
1449     if (!membershipsArray.isEmpty()) {
1450         returnObject.insert(QStringLiteral("memberships"), membershipsArray);
1451     }
1452 
1453     QJsonArray miscKeywordsArray;
1454     for (const auto &miscKeyword : std::as_const(d->miscKeywords)) {
1455         miscKeywordsArray.append(miscKeyword.toJSON());
1456     }
1457     if (!miscKeywordsArray.isEmpty()) {
1458         returnObject.insert(QStringLiteral("miscKeywords"), miscKeywordsArray);
1459     }
1460 
1461     QJsonArray namesArray;
1462     for (const auto &name : std::as_const(d->names)) {
1463         namesArray.append(name.toJSON());
1464     }
1465     if (!namesArray.isEmpty()) {
1466         returnObject.insert(QStringLiteral("names"), namesArray);
1467     }
1468 
1469     QJsonArray nicknamesArray;
1470     for (const auto &nickname : std::as_const(d->nicknames)) {
1471         nicknamesArray.append(nickname.toJSON());
1472     }
1473     if (!nicknamesArray.isEmpty()) {
1474         returnObject.insert(QStringLiteral("nicknames"), nicknamesArray);
1475     }
1476 
1477     QJsonArray occupationsArray;
1478     for (const auto &occupation : std::as_const(d->occupations)) {
1479         occupationsArray.append(occupation.toJSON());
1480     }
1481     if (!occupationsArray.isEmpty()) {
1482         returnObject.insert(QStringLiteral("occupations"), occupationsArray);
1483     }
1484 
1485     QJsonArray organizationsArray;
1486     for (const auto &organization : std::as_const(d->organizations)) {
1487         organizationsArray.append(organization.toJSON());
1488     }
1489     if (!organizationsArray.isEmpty()) {
1490         returnObject.insert(QStringLiteral("organizations"), organizationsArray);
1491     }
1492 
1493     QJsonArray phoneNumbersArray;
1494     for (const auto &phoneNumber : std::as_const(d->phoneNumbers)) {
1495         phoneNumbersArray.append(phoneNumber.toJSON());
1496     }
1497     if (!phoneNumbersArray.isEmpty()) {
1498         returnObject.insert(QStringLiteral("phoneNumbers"), phoneNumbersArray);
1499     }
1500 
1501     /* Output only field
1502     QJsonArray photosArray;
1503     for (const auto &photo : d->photos) {
1504         photosArray.append(photo.toJSON());
1505     }
1506     if (!photosArray.isEmpty()) {
1507         returnObject.insert(QStringLiteral("photos"), photosArray);
1508     }
1509     */
1510 
1511     QJsonArray relationsArray;
1512     for (const auto &relation : std::as_const(d->relations)) {
1513         relationsArray.append(relation.toJSON());
1514     }
1515     if (!relationsArray.isEmpty()) {
1516         returnObject.insert(QStringLiteral("relations"), relationsArray);
1517     }
1518 
1519     // relationshipInterest is deprecated, provides no data
1520     // relationshipStatus is also deprecated
1521     // residence is also deprecated
1522 
1523     QJsonArray sipAddressesArray;
1524     for (const auto &sipAddress : std::as_const(d->sipAddresses)) {
1525         sipAddressesArray.append(sipAddress.toJSON());
1526     }
1527     if (!sipAddressesArray.isEmpty()) {
1528         returnObject.insert(QStringLiteral("sipAddresses"), sipAddressesArray);
1529     }
1530 
1531     QJsonArray skillsArray;
1532     for (const auto &skill : std::as_const(d->skills)) {
1533         skillsArray.append(skill.toJSON());
1534     }
1535     if (!skillsArray.isEmpty()) {
1536         returnObject.insert(QStringLiteral("skills"), skillsArray);
1537     }
1538 
1539     QJsonArray urlsArray;
1540     for (const auto &url : std::as_const(d->urls)) {
1541         urlsArray.append(url.toJSON());
1542     }
1543     if (!urlsArray.isEmpty()) {
1544         returnObject.insert(QStringLiteral("urls"), urlsArray);
1545     }
1546 
1547     QJsonArray userDefinedArray;
1548     for (const auto &userDefined : std::as_const(d->userDefined)) {
1549         userDefinedArray.append(userDefined.toJSON());
1550     }
1551     if (!userDefinedArray.isEmpty()) {
1552         returnObject.insert(QStringLiteral("userDefined"), userDefinedArray);
1553     }
1554 
1555     return returnObject;
1556 }
1557 
1558 KContacts::Addressee Person::toKContactsAddressee() const
1559 {
1560     return d->toKContactsAddressee();
1561 }
1562 
1563 PersonPtr Person::fromKContactsAddressee(const KContacts::Addressee &addressee)
1564 {
1565     auto person = new Person;
1566     person->d->setFromKContactsAddressee(addressee);
1567     return PersonPtr(person);
1568 }
1569 
1570 bool Person::operator==(const Person &other) const
1571 {
1572     if (!Object::operator==(other)) {
1573         return false;
1574     }
1575 
1576     if (d->resourceName != other.d->resourceName) {
1577         qCDebug(KGAPIDebug) << "Resource name does not match"
1578                             << d->resourceName
1579                             << other.d->resourceName;
1580         return false;
1581     }
1582     if (d->etag != other.d->etag) {
1583         qCDebug(KGAPIDebug) << "Etag does not match"
1584                             << d->etag
1585                             << other.d->etag;
1586         return false;
1587     }
1588     if (d->metadata != other.d->metadata) {
1589         qCDebug(KGAPIDebug) << "Metadata does not match"
1590                             << d->metadata.deleted() << other.d->metadata.deleted()
1591                             << d->metadata.linkedPeopleResourceNames() << other.d->metadata.linkedPeopleResourceNames()
1592                             << d->metadata.previousResourceNames() << other.d->metadata.previousResourceNames();
1593         return false;
1594     }
1595 
1596     return *d.get() == *d.get();
1597 }
1598 
1599 } // namespace KGAPI2::People