diff --git a/include/faker-cxx/Commerce.h b/include/faker-cxx/Commerce.h index 765ea6754..fdc149af7 100644 --- a/include/faker-cxx/Commerce.h +++ b/include/faker-cxx/Commerce.h @@ -85,5 +85,49 @@ class Commerce * @endcode */ static std::string productFullName(); + + /** + * @brief Returns a random valid ean13 code. + * + * @returns Ean13 code. + * + * @code + * Commerce::EAN13() // "1234567890128" + * @endcode + */ + static std::string EAN13(); + + /** + * @brief Returns a random valid ean8 code. + * + * @returns Ean8 code. + * + * @code + * Commerce::EAN8() // "90311017" + * @endcode + */ + static std::string EAN8(); + + /** + * @brief Returns a random valid isbn13 code. + * + * @returns Isbn13 code. + * + * @code + * Commerce::ISBN13() // "9781234567897" + * @endcode + */ + static std::string ISBN13(); + + /** + * @brief Returns a random valid ISBN10 code. + * + * @returns Isbn10 code. + * + * @code + * Commerce::ISBN10() // "0200716018" + * @endcode + */ + static std::string ISBN10(); }; } diff --git a/src/modules/commerce/Commerce.cpp b/src/modules/commerce/Commerce.cpp index b7f1e9443..f83385b5d 100644 --- a/src/modules/commerce/Commerce.cpp +++ b/src/modules/commerce/Commerce.cpp @@ -42,4 +42,100 @@ std::string Commerce::productFullName() { return fmt::format("{} {} {}", productAdjective(), productMaterial(), productName()); } + +std::string Commerce::EAN13() +{ + std::string ean13 = String::numeric(12, false); + + int sum = 0; + for (size_t i = 0; i < 12; i++) + { + if (i % 2 == 0) { + sum += (ean13[i] - '0'); + } + else { + sum += 3 * (ean13[i] - '0'); + } + } + + int checkDigit = sum % 10; + + if (checkDigit != 0) { + checkDigit = 10 - checkDigit; + } + + return ean13 + std::to_string(checkDigit); +} + +std::string Commerce::EAN8() +{ + std::string ean8 = String::numeric(7, false); + + int sum = 0; + for (size_t i = 0; i < 7; i++) + { + if (i % 2 == 0) { + sum += 3 * (ean8[i] - '0'); + } + else { + sum += (ean8[i] - '0'); + } + } + + int checkDigit = sum % 10; + + if (checkDigit != 0) { + checkDigit = 10 - checkDigit; + } + + return ean8 + std::to_string(checkDigit); +} + +std::string Commerce::ISBN13() +{ + std::string isbn13 = String::numeric(12, true); + + int sum = 0; + for (size_t i = 0; i < 12; i++) + { + if (i % 2 == 0) { + sum += (isbn13[i] - '0'); + } + else { + sum += 3 * (isbn13[i] - '0'); + } + } + + int checkDigit = sum % 10; + + if (checkDigit != 0) { + checkDigit = 10 - checkDigit; + } + + return isbn13 + std::to_string(checkDigit); +} + +std::string Commerce::ISBN10() +{ + std::string isbn10 = String::numeric(9, true); + + int sum = 0, weight = 10; + for (size_t i = 0; i < 9; i++) + { + sum += (isbn10[i] - '0') * weight; + weight--; + } + + int checkDigit = sum % 11; + + if (checkDigit != 0) { + checkDigit = 11 - checkDigit; + } + + if (checkDigit == 10) { + return isbn10 + "X"; + } + + return isbn10 + std::to_string(checkDigit); +} } diff --git a/src/modules/commerce/CommerceTest.cpp b/src/modules/commerce/CommerceTest.cpp index ed49b5248..7fb206efd 100644 --- a/src/modules/commerce/CommerceTest.cpp +++ b/src/modules/commerce/CommerceTest.cpp @@ -111,3 +111,85 @@ TEST_F(CommerceTest, shouldGenerateProductName) ASSERT_TRUE(std::ranges::any_of(productNames, [generatedProductName](const std::string& productName) { return productName == generatedProductName; })); } + +TEST_F(CommerceTest, shouldGenerateEan13) +{ + const auto generatedEan13 = Commerce::EAN13(); + + int sum = 0; + for (size_t i = 0; i < 13; i++) + { + if (i % 2 == 0) { + sum += (generatedEan13[i] - '0'); + } + else { + sum += 3 * (generatedEan13[i] - '0'); + } + } + + ASSERT_EQ(generatedEan13.size(), 13); + ASSERT_TRUE(sum % 10 == 0); +} + +TEST_F(CommerceTest, shouldGenerateEan8) +{ + const auto generatedEan8 = Commerce::EAN8(); + + int sum = 0; + for (size_t i = 0; i < 8; i++) + { + if (i % 2 == 0) { + sum += 3 * (generatedEan8[i] - '0'); + } + else { + sum += (generatedEan8[i] - '0'); + } + } + + ASSERT_EQ(generatedEan8.size(), 8); + ASSERT_TRUE(sum % 10 == 0); +} + +TEST_F(CommerceTest, shouldGenerateIsbn13) +{ + const auto generatedIsbn13 = Commerce::ISBN13(); + + int sum = 0; + for (size_t i = 0; i < 13; i++) + { + if (i % 2 == 0) { + sum += (generatedIsbn13[i] - '0'); + } + else { + sum += 3 * (generatedIsbn13[i] - '0'); + } + } + + ASSERT_EQ(generatedIsbn13.size(), 13); + ASSERT_TRUE(sum % 10 == 0); +} + +TEST_F(CommerceTest, shouldGenerateIsbn10) +{ + const auto generatedIsbn10 = Commerce::ISBN10(); + + int sum = 0, weight = 10; + if (generatedIsbn10[9] == 'X') { + for (size_t i = 0; i < 9; i++) + { + sum += (generatedIsbn10[i] - '0') * weight; + weight--; + } + sum += 10; + } + else { + for (size_t i = 0; i < 10; i++) + { + sum += (generatedIsbn10[i] - '0') * weight; + weight--; + } + } + + ASSERT_EQ(generatedIsbn10.size(), 10); + ASSERT_TRUE(sum % 11 == 0); +}