M module-apps/application-phonebook/windows/PhonebookNewContact.cpp => module-apps/application-phonebook/windows/PhonebookNewContact.cpp +6 -4
@@ 149,10 149,10 @@ namespace gui
case DBServiceAPI::ContactVerificationResult::emptyContact:
return false;
case DBServiceAPI::ContactVerificationResult::primaryNumberDuplicate:
- showDialogDuplicatedNumber(contact->numbers[0].number);
+ showDialogDuplicatedNumber(contact->numbers[0].number, contact->ID);
return false;
case DBServiceAPI::ContactVerificationResult::secondaryNumberDuplicate:
- showDialogDuplicatedNumber(contact->numbers[1].number);
+ showDialogDuplicatedNumber(contact->numbers[1].number, contact->ID);
return false;
case DBServiceAPI::ContactVerificationResult::speedDialDuplicate:
showDialogDuplicatedSpeedDialNumber();
@@ 191,9 191,11 @@ namespace gui
return true;
} // namespace gui
- void PhonebookNewContact::showDialogDuplicatedNumber(const utils::PhoneNumber::View &duplicatedNumber)
+ void PhonebookNewContact::showDialogDuplicatedNumber(const utils::PhoneNumber::View &duplicatedNumber,
+ const std::uint32_t duplicatedNumberContactID)
{
- auto matchedContact = DBServiceAPI::MatchContactByPhoneNumber(application, duplicatedNumber);
+ auto matchedContact =
+ DBServiceAPI::MatchContactByPhoneNumber(application, duplicatedNumber, duplicatedNumberContactID);
auto oldContactRecord = (matchedContact != nullptr) ? *matchedContact : ContactRecord{};
auto metaData = std::make_unique<gui::DialogMetadataMessage>(
gui::DialogMetadata{duplicatedNumber.getFormatted(),
M module-apps/application-phonebook/windows/PhonebookNewContact.hpp => module-apps/application-phonebook/windows/PhonebookNewContact.hpp +3 -2
@@ 1,4 1,4 @@
-// Copyright (c) 2017-2021, Mudita Sp. z.o.o. All rights reserved.
+// Copyright (c) 2017-2022, Mudita Sp. z.o.o. All rights reserved.
// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md
#pragma once
@@ 35,7 35,8 @@ namespace gui
};
auto verifyAndSave() -> bool;
- void showDialogDuplicatedNumber(const utils::PhoneNumber::View &duplicatedNumber);
+ void showDialogDuplicatedNumber(const utils::PhoneNumber::View &duplicatedNumber,
+ const std::uint32_t duplicatedNumberContactID = 0u);
void showDialogDuplicatedSpeedDialNumber();
void setSaveButtonVisible(bool visible);
M module-db/Interface/ContactRecord.cpp => module-db/Interface/ContactRecord.cpp +37 -7
@@ 123,10 123,37 @@ auto ContactRecordInterface::Update(const ContactRecord &rec) -> bool
return false;
}
- auto oldNumberIDs = splitNumberIDs(contact.numbersID);
- auto newNumbersIDs = getNumbersIDs(contact.ID, rec);
+ auto oldNumberIDs = splitNumberIDs(contact.numbersID);
+
+ /* Changing number table record in place if new number is same as old number but with/without country code */
+ auto numberMatcher = buildNumberMatcher(NumberMatcherPageSize);
+ for (const auto oldNumberID : oldNumberIDs) { // pick one of the old number for this contactID (from DB)
+ auto numberRecord = contactDB->number.getById(oldNumberID);
+ utils::PhoneNumber oldPhoneNumber(numberRecord.numberUser, numberRecord.numbere164);
+ for (const auto &newNumberID : rec.numbers) { // pick one of the new number from &rec
+ utils::PhoneNumber newPhoneNumber(newNumberID.number);
+ // if DB have not such a new number already and if one of this have country code and other doesn't
+ if (!numberMatcher.bestMatch(newPhoneNumber, utils::PhoneNumber::Match::EXACT).has_value() &&
+ (newPhoneNumber.match(oldPhoneNumber) == utils::PhoneNumber::Match::POSSIBLE) &&
+ ((!oldPhoneNumber.isValid() && newPhoneNumber.isValid()) ||
+ (oldPhoneNumber.isValid() && !newPhoneNumber.isValid()))) {
+ // which means that only country code is to add or remove (change of country code is not supported here)
+ // then change old number record in number table to the new number
+ auto oldNumberRecordToUpdate = contactDB->number.getById(oldNumberID);
+ oldNumberRecordToUpdate.numberUser = newPhoneNumber.get();
+ oldNumberRecordToUpdate.numbere164 = newPhoneNumber.toE164();
+ if (!contactDB->number.update(oldNumberRecordToUpdate)) {
+ return false;
+ }
+ }
+ }
+ }
+
+ auto newNumbersIDs = getNumbersIDs(contact.ID, rec, utils::PhoneNumber::Match::EXACT);
for (auto oldNumberID : oldNumberIDs) {
if (std::find(std::begin(newNumbersIDs), std::end(newNumbersIDs), oldNumberID) == std::end(newNumbersIDs)) {
+ // If any oldNumberID is NOT one of the newNumbersID, which will be assigned to this contact, then
+ // make temporary contact with this oldNumberID
auto numberRecord = contactDB->number.getById(oldNumberID);
if (!numberRecord.isValid()) {
return false;
@@ 141,6 168,7 @@ auto ContactRecordInterface::Update(const ContactRecord &rec) -> bool
e.what());
return false;
}
+ // make temporary contact with old number
const auto tmpContactRecord = addTemporaryContactForNumber(number);
if (!tmpContactRecord.has_value()) {
return false;
@@ 195,8 223,9 @@ auto ContactRecordInterface::Update(const ContactRecord &rec) -> bool
return true;
}
-auto ContactRecordInterface::getNumbersIDs(std::uint32_t contactID, const ContactRecord &contact)
- -> std::vector<std::uint32_t>
+auto ContactRecordInterface::getNumbersIDs(std::uint32_t contactID,
+ const ContactRecord &contact,
+ utils::PhoneNumber::Match matchLevel) -> std::vector<std::uint32_t>
{
std::vector<std::uint32_t> result;
@@ 213,7 242,7 @@ auto ContactRecordInterface::getNumbersIDs(std::uint32_t contactID, const Contac
return {};
}
- auto numberMatch = numberMatcher.bestMatch(phoneNumber, utils::PhoneNumber::Match::POSSIBLE);
+ auto numberMatch = numberMatcher.bestMatch(phoneNumber, matchLevel);
if (!numberMatch.has_value()) {
// number does not exist in the DB yet. Let's add it.
if (!contactDB->number.add(ContactsNumberTableRow{Record(DB_ID_NONE),
@@ 1211,7 1240,8 @@ auto ContactRecordInterface::buildNumberMatcher(unsigned int maxPageSize)
auto ContactRecordInterface::MatchByNumber(const utils::PhoneNumber::View &numberView,
CreateTempContact createTempContact,
- utils::PhoneNumber::Match matchLevel)
+ utils::PhoneNumber::Match matchLevel,
+ const std::uint32_t contactIDToIgnore)
-> std::optional<ContactRecordInterface::ContactNumberMatch>
{
utils::PhoneNumber phoneNumber;
@@ 1225,7 1255,7 @@ auto ContactRecordInterface::MatchByNumber(const utils::PhoneNumber::View &numbe
}
auto numberMatcher = buildNumberMatcher(NumberMatcherPageSize);
- auto matchedNumber = numberMatcher.bestMatch(phoneNumber, matchLevel);
+ auto matchedNumber = numberMatcher.bestMatch(phoneNumber, matchLevel, contactIDToIgnore);
if (!matchedNumber.has_value()) {
if (createTempContact != CreateTempContact::True) {
return std::nullopt;
M module-db/Interface/ContactRecord.hpp => module-db/Interface/ContactRecord.hpp +7 -4
@@ 206,9 206,9 @@ class ContactRecordInterface : public RecordInterface<ContactRecord, ContactReco
auto GetByNumberID(std::uint32_t numberId) -> std::optional<ContactRecord>;
auto MatchByNumber(const utils::PhoneNumber::View &numberView,
- CreateTempContact createTempContact = CreateTempContact::False,
- utils::PhoneNumber::Match matchLevel = utils::PhoneNumber::Match::POSSIBLE)
- -> std::optional<ContactNumberMatch>;
+ CreateTempContact createTempContact = CreateTempContact::False,
+ utils::PhoneNumber::Match matchLevel = utils::PhoneNumber::Match::POSSIBLE,
+ const std::uint32_t contactIDToIgnore = 0u) -> std::optional<ContactNumberMatch>;
auto GetBySpeedDial(const UTF8 &speedDial) -> std::unique_ptr<std::vector<ContactRecord>>;
@@ 289,7 289,10 @@ class ContactRecordInterface : public RecordInterface<ContactRecord, ContactReco
-> const std::unique_ptr<db::QueryResult>;
auto addTemporaryContactForNumber(const ContactRecord::Number &number) -> std::optional<ContactRecord>;
- auto getNumbersIDs(std::uint32_t contactID, const ContactRecord &contact) -> std::vector<std::uint32_t>;
+ auto getNumbersIDs(std::uint32_t contactID,
+ const ContactRecord &contact,
+ utils::PhoneNumber::Match matchLevel = utils::PhoneNumber::Match::POSSIBLE)
+ -> std::vector<std::uint32_t>;
auto addNumbers(std::uint32_t contactID, const std::vector<ContactRecord::Number> &numbers)
-> std::optional<std::string>;
auto addOrUpdateName(std::uint32_t contactID, std::uint32_t nameID, const ContactRecord &contact)
M module-db/tests/ContactsRecord_tests.cpp => module-db/tests/ContactsRecord_tests.cpp +105 -1
@@ 264,7 264,12 @@ TEST_CASE("Contact record numbers update")
auto records = ContactRecordInterface(&contactDB);
ContactRecord testRecord, otherRecord;
- std::array<std::string, 4> numbers = {{{"600100100"}, {"600100200"}, {"600100300"}, {"600100400"}}};
+ std::array<std::string, 4> numbers = {{{"600100100"}, {"600100200"}, {"600100300"}, {"600100400"}}};
+ std::array<std::string, 4> numbersPL = {
+ {{"+48600100100"}, {"+48600100200"}, {"+48600100300"}, {"+48600100400"}}}; // Poland country code
+ std::array<std::string, 4> numbersFR = {
+ {{"+33600100100"}, {"+33600100200"}, {"+33600100300"}, {"+33600100400"}}}; // France country code
+ std::array<std::string, 2> unUsedNumbers = {{{"612130140"}, {"612130141"}}};
testRecord.primaryName = "number";
testRecord.alternativeName = "test";
@@ 369,6 374,105 @@ TEST_CASE("Contact record numbers update")
REQUIRE(validatationRecord.numbers[0].number.getEntered() == numbers[3]);
}
+ SECTION("Single number update - adding country code")
+ {
+ auto newRecord = records.GetByID(1);
+ REQUIRE(newRecord.numbers.size() == 2);
+
+ newRecord.numbers = std::vector<ContactRecord::Number>({ContactRecord::Number(numbersPL[0], std::string("")),
+ ContactRecord::Number(numbersFR[1], std::string(""))});
+ REQUIRE(records.Update(newRecord));
+ REQUIRE(contactDB.number.count() == 4);
+
+ auto validationRecord = records.GetByID(1);
+ REQUIRE(validationRecord.numbers.size() == 2);
+ REQUIRE(validationRecord.numbers[0].number.getEntered() == numbersPL[0]);
+ REQUIRE(validationRecord.numbers[1].number.getEntered() == numbersFR[1]);
+
+ validationRecord = records.GetByID(2);
+ REQUIRE(validationRecord.numbers.size() == 2);
+ REQUIRE(validationRecord.numbers[0].number.getEntered() == numbers[2]);
+
+ // There is no new temporary contact
+ validationRecord = records.GetByIdWithTemporary(3);
+ REQUIRE(validationRecord.ID == DB_ID_NONE);
+ REQUIRE(validationRecord.numbers.empty());
+ }
+
+ SECTION("Single number update - removing country code")
+ {
+ auto newRecord = records.GetByID(1);
+ REQUIRE(newRecord.numbers.size() == 2);
+
+ // add country code
+ newRecord.numbers = std::vector<ContactRecord::Number>({ContactRecord::Number(numbersPL[0], std::string("")),
+ ContactRecord::Number(numbersFR[1], std::string(""))});
+ REQUIRE(records.Update(newRecord));
+ REQUIRE(contactDB.number.count() == 4);
+
+ // deleting country code
+ newRecord.numbers = std::vector<ContactRecord::Number>(
+ {ContactRecord::Number(numbers[0], std::string("")), ContactRecord::Number(numbers[1], std::string(""))});
+ REQUIRE(records.Update(newRecord));
+ REQUIRE(contactDB.number.count() == 4);
+
+ auto validationRecord = records.GetByID(1);
+ REQUIRE(validationRecord.numbers.size() == 2);
+ REQUIRE(validationRecord.numbers[0].number.getEntered() == numbers[0]);
+ REQUIRE(validationRecord.numbers[1].number.getEntered() == numbers[1]);
+
+ validationRecord = records.GetByID(2);
+ REQUIRE(validationRecord.numbers.size() == 2);
+ REQUIRE(validationRecord.numbers[0].number.getEntered() == numbers[2]);
+
+ // There is no new temporary contact
+ validationRecord = records.GetByIdWithTemporary(3);
+ REQUIRE(validationRecord.ID == DB_ID_NONE);
+ REQUIRE(validationRecord.numbers.empty());
+ }
+
+ SECTION("Single number update - changing country code")
+ {
+ auto newRecord = records.GetByID(1);
+ REQUIRE(newRecord.numbers.size() == 2);
+
+ // add country code (PL)
+ newRecord.numbers = std::vector<ContactRecord::Number>({ContactRecord::Number(numbersPL[0], std::string("")),
+ ContactRecord::Number(numbersPL[1], std::string(""))});
+ REQUIRE(records.Update(newRecord));
+ REQUIRE(contactDB.number.count() == 4);
+
+ // changing country code (to FR)
+ newRecord.numbers = std::vector<ContactRecord::Number>({ContactRecord::Number(numbersFR[0], std::string("")),
+ ContactRecord::Number(numbersFR[1], std::string(""))});
+ REQUIRE(records.Update(newRecord));
+ REQUIRE(contactDB.number.count() == 6);
+ REQUIRE(contactDB.number.getById(1).contactID != 1); // old numbers do not belong to any contact
+ REQUIRE(contactDB.number.getById(1).contactID != 2);
+ REQUIRE(contactDB.number.getById(2).contactID != 1);
+ REQUIRE(contactDB.number.getById(2).contactID != 2);
+
+ auto validationRecord = records.GetByID(1);
+ REQUIRE(validationRecord.numbers.size() == 2);
+ REQUIRE(validationRecord.numbers[0].number.getEntered() == numbersFR[0]);
+ REQUIRE(validationRecord.numbers[1].number.getEntered() == numbersFR[1]);
+
+ validationRecord = records.GetByID(2);
+ REQUIRE(validationRecord.numbers.size() == 2);
+ REQUIRE(validationRecord.numbers[0].number.getEntered() == numbers[2]);
+
+ // A temporary contact for number ID 1 (which was previously assigned to recordID=1) has been created.
+ validationRecord = records.GetByIdWithTemporary(3);
+ REQUIRE(validationRecord.ID != DB_ID_NONE);
+ REQUIRE(validationRecord.numbers[0].number.getEntered() == numbersPL[0]);
+
+ // A temporary contact for numberID 2 (which was previously assigned to recordID=2 for a moment) has been
+ // created.
+ validationRecord = records.GetByIdWithTemporary(4);
+ REQUIRE(validationRecord.ID != DB_ID_NONE);
+ REQUIRE(validationRecord.numbers[0].number.getEntered() == numbersPL[1]);
+ }
+
SECTION("Change both numbers")
{
auto newRecord = records.GetByID(1);
M module-services/service-db/DBServiceAPI.cpp => module-services/service-db/DBServiceAPI.cpp +6 -5
@@ 68,10 68,11 @@ auto DBServiceAPI::ContactGetBySpeeddial(sys::Service *serv, UTF8 speeddial)
return ContactGetByIDCommon(serv, msg);
}
-auto DBServiceAPI::MatchContactByPhoneNumber(sys::Service *serv, const utils::PhoneNumber::View &numberView)
- -> std::unique_ptr<ContactRecord>
+auto DBServiceAPI::MatchContactByPhoneNumber(sys::Service *serv,
+ const utils::PhoneNumber::View &numberView,
+ const std::uint32_t contactIDToOmit) -> std::unique_ptr<ContactRecord>
{
- auto msg = std::make_shared<DBContactNumberMessage>(numberView);
+ auto msg = std::make_shared<DBMatchContactNumberBesidesOfContactIDMessage>(numberView, contactIDToOmit);
auto ret = serv->bus.sendUnicastSync(std::move(msg), service::name::db, DefaultTimeoutInMs);
auto contactResponse = dynamic_cast<DBContactNumberResponseMessage *>(ret.second.get());
@@ 139,8 140,8 @@ auto DBServiceAPI::verifyContact(sys::Service *serv, const ContactRecord &rec)
}
if (rec.numbers.size() > 0 && rec.numbers[0].number.getEntered().size() > 0) {
- auto retPhone1 = MatchContactByPhoneNumber(serv, rec.numbers[0].number);
- if (retPhone1 && retPhone1->ID != rec.ID) {
+ auto retPhone1 = MatchContactByPhoneNumber(serv, rec.numbers[0].number, rec.ID);
+ if (retPhone1) {
if (retPhone1->isTemporary()) {
return ContactVerificationResult::temporaryContactExists;
}
M module-services/service-db/include/service-db/DBContactMessage.hpp => module-services/service-db/include/service-db/DBContactMessage.hpp +37 -1
@@ 1,4 1,4 @@
-// Copyright (c) 2017-2021, Mudita Sp. z.o.o. All rights reserved.
+// Copyright (c) 2017-2022, Mudita Sp. z.o.o. All rights reserved.
// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md
#pragma once
@@ 62,6 62,42 @@ class DBContactNumberMessage : public sys::DataMessage
};
/**
+ * @brief Message used to match Contact by an instance of PhoneNumber::View while omitting the specific contactID.
+ * Omitting specific Contact during searching is helpful to ignore the number which is already signed to Contact
+ * that we want to find a matching number for
+ *
+ */
+class DBMatchContactNumberBesidesOfContactIDMessage : public sys::DataMessage
+{
+ public:
+ /**
+ * @brief Construct a new DBMatchContactNumberBesidesOfContactIDMessage object
+ *
+ * @param numberView - a number to match with
+ */
+
+ DBMatchContactNumberBesidesOfContactIDMessage(const utils::PhoneNumber::View &numberView,
+ std::uint32_t contactIDToOmit);
+ /**
+ * @brief Destroy the DBMatchContactNumberBesidesOfContactIDMessage object
+ *
+ */
+ virtual ~DBMatchContactNumberBesidesOfContactIDMessage();
+
+ /**
+ * @brief number to match with
+ *
+ */
+ utils::PhoneNumber::View numberView;
+
+ /**
+ * @brief numbers connected with this contact Id are omitting during the searching
+ *
+ */
+ std::uint32_t contactIDToOmit;
+};
+
+/**
* @brief A response to DBContactNumberMessage - returns an instance of a ContactRecord matched by provided
* PhoneNumber::View
*
M module-services/service-db/include/service-db/DBServiceAPI.hpp => module-services/service-db/include/service-db/DBServiceAPI.hpp +4 -1
@@ 92,9 92,12 @@ class DBServiceAPI
*
* @param serv - calling service
* @param numberView - number to match contact with
+ * @param contactIDToOmit - for this contact ID the match will be ignored
* @return std::unique_ptr<ContactRecord>
*/
- [[deprecated]] static auto MatchContactByPhoneNumber(sys::Service *serv, const utils::PhoneNumber::View &numberView)
+ [[deprecated]] static auto MatchContactByPhoneNumber(sys::Service *serv,
+ const utils::PhoneNumber::View &numberView,
+ const std::uint32_t contactIDToOmit = 0u)
-> std::unique_ptr<ContactRecord>;
[[deprecated]] static auto MatchContactByNumberID(sys::Service *serv, std::uint32_t numberID)
-> std::unique_ptr<ContactRecord>;
M module-services/service-db/messages/DBContactMessage.cpp => module-services/service-db/messages/DBContactMessage.cpp +9 -0
@@ 36,6 36,15 @@ DBContactNumberMessage::DBContactNumberMessage(const utils::PhoneNumber::View &n
DBContactNumberMessage::~DBContactNumberMessage()
{}
+DBMatchContactNumberBesidesOfContactIDMessage::DBMatchContactNumberBesidesOfContactIDMessage(
+ const utils::PhoneNumber::View &numberView, std::uint32_t contactIDToOmit)
+ : sys::DataMessage(MessageType::DBMatchContactNumberBesidesOfContactID), numberView(numberView),
+ contactIDToOmit(contactIDToOmit)
+{}
+
+DBMatchContactNumberBesidesOfContactIDMessage::~DBMatchContactNumberBesidesOfContactIDMessage()
+{}
+
DBContactNumberResponseMessage::DBContactNumberResponseMessage(sys::ReturnCodes retCode,
std::unique_ptr<ContactRecord> contact)
: sys::ResponseMessage(retCode, MessageType::DBContactMatchByNumber), contact(std::move(contact))
M module-utils/phonenumber/NumberHolderMatcher.hpp => module-utils/phonenumber/NumberHolderMatcher.hpp +7 -4
@@ 58,10 58,12 @@ namespace utils
*
* @param other - number to match with
* @param level - minimum acceptable match level
+ * @param contactIDToIgnore - for this contact ID the match will be ignored
* @return Best match for the other phone number
*/
std::optional<THolder> bestMatch(const PhoneNumber &phoneNumber,
- PhoneNumber::Match level = PhoneNumber::Match::EXACT)
+ PhoneNumber::Match level = PhoneNumber::Match::EXACT,
+ const std::uint32_t contactIDToIgnore = 0u)
{
utils::time::Scoped t{"bestMatch()"};
// if empty string, do not try to match, simply return
@@ 71,9 73,10 @@ namespace utils
restartFor(phoneNumber);
do {
- const auto it =
- std::find_if(numbers.cbegin(), numbers.cend(), [&phoneNumber, level](const auto &number) {
- return phoneNumber.match(number.getNumber()) >= level;
+ const auto it = std::find_if(
+ numbers.cbegin(), numbers.cend(), [&phoneNumber, level, contactIDToIgnore](const auto &number) {
+ return (phoneNumber.match(number.getNumber()) >= level) &&
+ (number.getContactID() != contactIDToIgnore);
});
if (it != numbers.cend()) {
return *it;
M module-utils/phonenumber/tests/unittest_numbermatcher.cpp => module-utils/phonenumber/tests/unittest_numbermatcher.cpp +14 -3
@@ 1,4 1,4 @@
-// Copyright (c) 2017-2021, Mudita Sp. z.o.o. All rights reserved.
+// Copyright (c) 2017-2022, Mudita Sp. z.o.o. All rights reserved.
// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md
#include <catch2/catch.hpp>
@@ 16,15 16,26 @@ using namespace utils;
class DummyHolder
{
PhoneNumber number;
+ static std::uint32_t dummyHolderCount; // init by 0
+ std::uint32_t contactID;
public:
- DummyHolder(const PhoneNumber &number) : number(number)
- {}
+ DummyHolder(const PhoneNumber &number, const std::uint32_t contactID = 0u) : number(number), contactID(contactID)
+ {
+ if (contactID == 0)
+ this->contactID = ++dummyHolderCount;
+ }
const PhoneNumber &getNumber() const
{
return number;
}
+
+ const decltype(contactID) &getContactID() const
+ {
+ return contactID;
+ }
};
+std::uint32_t DummyHolder::dummyHolderCount = 0u;
static constexpr auto DefaultPageSize = 1; // so the paging mechanism is checked.
M products/PurePhone/services/db/ServiceDB.cpp => products/PurePhone/services/db/ServiceDB.cpp +18 -0
@@ 133,6 133,24 @@ sys::MessagePointer ServiceDB::DataReceivedHandler(sys::DataMessage *msgl, sys::
}
} break;
+ case MessageType::DBMatchContactNumberBesidesOfContactID: {
+ auto time = utils::time::Scoped("DBMatchContactNumberBesidesOfContactID");
+ auto *msg = dynamic_cast<DBMatchContactNumberBesidesOfContactIDMessage *>(msgl);
+ auto ret = contactRecordInterface->MatchByNumber(msg->numberView,
+ ContactRecordInterface::CreateTempContact::False,
+ utils::PhoneNumber::Match::POSSIBLE,
+ msg->contactIDToOmit);
+
+ if (ret.has_value()) {
+ responseMsg = std::make_shared<DBContactNumberResponseMessage>(
+ sys::ReturnCodes::Success, std::make_unique<ContactRecord>(std::move(ret->contact)));
+ }
+ else {
+ responseMsg = std::make_shared<DBContactNumberResponseMessage>(sys::ReturnCodes::Success,
+ std::unique_ptr<ContactRecord>());
+ }
+ } break;
+
case MessageType::DBContactMatchByNumberID: {
auto time = utils::time::Scoped("DBContactMatchByNumberID");
auto *msg = dynamic_cast<DBMatchContactByNumberIDMessage *>(msgl);
M pure_changelog.md => pure_changelog.md +1 -0
@@ 9,6 9,7 @@
* Fixed looping on the SIM card selection screen
* Fixed notes paste option showing for empty clipboard
* Fixed notes window title
+* Fixed adding and deleting country code prefix to existing contact
### Added
M source/MessageType.hpp => source/MessageType.hpp +4 -1
@@ 1,4 1,4 @@
-// Copyright (c) 2017-2021, Mudita Sp. z.o.o. All rights reserved.
+// Copyright (c) 2017-2022, Mudita Sp. z.o.o. All rights reserved.
// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md
#pragma once
@@ 26,6 26,9 @@ enum class MessageType
DBContactMatchByNumberID [[deprecated]],
DBContactMatchByNumber
[[deprecated]], ///< used to best match with a single contact using a phone number (primary or secondary)
+ DBMatchContactNumberBesidesOfContactID
+ [[deprecated]], ///< used to best match with a single contact using a phone number (primary or secondary)
+ ///< but witch omitting specific contact ID
DBContactAdd [[deprecated]], ///< Add contact record
DBContactRemove [[deprecated]], ///< Remove contact remove
DBContactUpdate [[deprecated]], ///< Update contact remove