diff --git a/LICENSE b/LICENSE index 335e2935e2c451e88156531d497e771b69bbb1cd..7997c876514b6295aa2839db1cd4ef8a2a9670ed 100644 --- a/LICENSE +++ b/LICENSE @@ -1,21 +1,21 @@ -MIT License - -Copyright (c) 2022 Liu Xia - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. +MIT License + +Copyright (c) 2022 Liu Xia + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/Makefile b/Makefile new file mode 100644 index 0000000000000000000000000000000000000000..a53bfede49688fd27b8faacd4fdef0ee237d9b3c --- /dev/null +++ b/Makefile @@ -0,0 +1,7 @@ +TestSource := Test/GroupBarcodesTest.cpp + #Test/CreateErrorReceiptTest.cpp Test/CreateReceiptTest.cpp \ + #Test/CreateValidReceiptTest.cpp Test/FormatReceiptTest.cpp Test/GroupBarcodesTest.cpp \ + #Test/ValidateBarcodeTest.cpp +all: + g++ -g *.cpp Test/*.cpp source/*.cpp -lgtest -lpthread -o TestRun + ./TestRun \ No newline at end of file diff --git a/Test.cpp b/Test.cpp new file mode 100644 index 0000000000000000000000000000000000000000..9340c833bcbcb94e9d92fae6a8ec6e979b34be62 --- /dev/null +++ b/Test.cpp @@ -0,0 +1,11 @@ +#include +#include +#include + +using namespace std; + +int main(int argc,char*argv[]) +{ + testing::InitGoogleTest(&argc,argv); + return RUN_ALL_TESTS(); +} \ No newline at end of file diff --git a/Test/CreateErrorReceiptTest.cpp b/Test/CreateErrorReceiptTest.cpp new file mode 100644 index 0000000000000000000000000000000000000000..d78414e6954b8e382d78c84f05d9521e44c9f335 --- /dev/null +++ b/Test/CreateErrorReceiptTest.cpp @@ -0,0 +1,34 @@ +#include +#include +#include +#include +#include +#include +#include "../include/common.h" +#include "../include/Receipt.h" + +using namespace std; + +TEST(CreateErrorReceiptListError, should_return_barcode_not_recognized) { + //given + Receipt receipt; + ValidationResultS validResult = {"", ERROR_LIST}; + + //when + string result = receipt.CreateErrorReceipt(validResult); + + //then + ASSERT_EQ("ERROR\n-------\nThe barcode cannot be recognized\n", result); +} + +TEST(CreateErrorReceiptProductError, should_return_product_not_found) { + //given + Receipt receipt; + ValidationResultS validResult = {"001", ERROR_PRODUCT}; + + //when + string result = receipt.CreateErrorReceipt(validResult); + + //then + ASSERT_EQ("ERROR\n-------\nThe product cannot be found: 001\n", result); +} \ No newline at end of file diff --git a/Test/CreateReceiptTest.cpp b/Test/CreateReceiptTest.cpp new file mode 100644 index 0000000000000000000000000000000000000000..678038221debc381f6a807e1f3ea13de23547e89 --- /dev/null +++ b/Test/CreateReceiptTest.cpp @@ -0,0 +1,48 @@ +#include +#include +#include +#include +#include +#include +#include "../include/common.h" +#include "../include/Receipt.h" + +using namespace std; + +TEST(CreateReceiptForMultiProduct, should_return_150_for_total_price) { + //given + Receipt receipt; + std::vector barcodesAndAmount = {{"001", 1}, + {"002", 4}, + {"003", 2}, + }; + + ProductsHash productsHash = {{"001", Product(string("product1"), 10)}, + {"002", Product(string("product2"), 20)}, + {"003", Product(string("product3"), 30)}, + }; + + //when + ReceiptWithTotalPriceS receiptWithTotalPriceResult = receipt.CreateReceipt(barcodesAndAmount, productsHash); + + //then + ASSERT_EQ(150, receiptWithTotalPriceResult.receiptTotalPrice); +} + +TEST(CreateReceiptForOneProduct, should_return_10_for_total_price) { + //given + Receipt receipt; + std::vector barcodesAndAmount = {{"001", 1}, + }; + + ProductsHash productsHash = {{"001", Product(string("product1"), 10)}, + {"002", Product(string("product2"), 20)}, + {"003", Product(string("product3"), 30)}, + }; + + //when + ReceiptWithTotalPriceS receiptWithTotalPriceResult = receipt.CreateReceipt(barcodesAndAmount, productsHash); + + //then + ASSERT_EQ(10, receiptWithTotalPriceResult.receiptTotalPrice); +} \ No newline at end of file diff --git a/Test/CreateValidReceiptTest.cpp b/Test/CreateValidReceiptTest.cpp new file mode 100644 index 0000000000000000000000000000000000000000..299c69914b9bdac62d2a82a6db0ebc063ba424d9 --- /dev/null +++ b/Test/CreateValidReceiptTest.cpp @@ -0,0 +1,51 @@ +#include +#include +#include +#include +#include +#include +#include "../include/common.h" +#include "../include/Receipt.h" + +using namespace std; + +TEST(CreateValidReceiptWithUniqProduct, should_return_110_total_price) { + //given + Receipt receipt; + std::vector selectedbarcodes = {"001-1", + "002-2", + "003-2", + }; + + ProductsHash productsHash = {{"001", Product(string("product1"), 10)}, + {"002", Product(string("product2"), 20)}, + {"003", Product(string("product3"), 30)}, + }; + + //when + string receiptContent = receipt.CreateValidReceipt(selectedbarcodes, productsHash); + + //then + ASSERT_EQ("Receipt\n-------\nName: product3, Amount: 2, Price: 30.000000, Total: 60.000000\nName: product2, Amount: 2, Price: 20.000000, Total: 40.000000\nName: product1, Amount: 1, Price: 10.000000, Total: 10.000000\n-------\nTotal: 110.000000\n", receiptContent); +} + +TEST(CreateValidReceiptWithSameProduct, should_return_150_total_price) { + //given + Receipt receipt; + std::vector selectedbarcodes = {"001-1", + "002-2", + "003-2", + "002-2", + }; + + ProductsHash productsHash = {{"001", Product(string("product1"), 10)}, + {"002", Product(string("product2"), 20)}, + {"003", Product(string("product3"), 30)}, + }; + + //when + string receiptContent = receipt.CreateValidReceipt(selectedbarcodes, productsHash); + + //then + ASSERT_EQ("Receipt\n-------\nName: product3, Amount: 2, Price: 30.000000, Total: 60.000000\nName: product2, Amount: 4, Price: 20.000000, Total: 80.000000\nName: product1, Amount: 1, Price: 10.000000, Total: 10.000000\n-------\nTotal: 150.000000\n", receiptContent); +} \ No newline at end of file diff --git a/Test/FormatReceiptTest.cpp b/Test/FormatReceiptTest.cpp new file mode 100644 index 0000000000000000000000000000000000000000..82ea00c0b1a156d94dc7c227984d639ad39db0b2 --- /dev/null +++ b/Test/FormatReceiptTest.cpp @@ -0,0 +1,58 @@ +#include +#include +#include +#include +#include +#include +#include "../include/common.h" +#include "../include/Receipt.h" + +using namespace std; + +TEST(FormatReceiptCaseBigValue, should_return_10000_for_total_price) { + //given + Receipt receipt; + ReceiptWithTotalPriceS receiptWithTotalPrice = { + { + { + {"product1", 3}, + 10, + 100, + }, + { + {"product2", 3}, + 10, + 100, + }, + }, + 10000, + }; + + //when + string receiptContent = receipt.FormatReceipt(receiptWithTotalPrice); + + //then + ASSERT_EQ("Receipt\n-------\nName: product1, Amount: 10, Price: 3.000000, Total: 100.000000\nName: product2, Amount: 10, Price: 3.000000, Total: 100.000000\n-------\nTotal: 10000.000000\n", receiptContent); +} + +TEST(FormatReceiptCaseSmallValue, should_return_1_for_total_price) { + //given + Receipt receipt; + ReceiptWithTotalPriceS receiptWithTotalPrice = { + { + { + {"product1", 3}, + 1, + 1, + }, + }, + 1, + }; + + //when + string receiptContent = receipt.FormatReceipt(receiptWithTotalPrice); + cout << receiptContent; + + //then + ASSERT_EQ("Receipt\n-------\nName: product1, Amount: 1, Price: 3.000000, Total: 1.000000\n-------\nTotal: 1.000000\n", receiptContent); +} \ No newline at end of file diff --git a/Test/GroupBarcodesTest.cpp b/Test/GroupBarcodesTest.cpp new file mode 100644 index 0000000000000000000000000000000000000000..0e1665d0de00aed69bee0b5bca8c24329c68e9ee --- /dev/null +++ b/Test/GroupBarcodesTest.cpp @@ -0,0 +1,40 @@ +#include +#include +#include +#include +#include +#include +#include "../include/common.h" +#include "../include/Receipt.h" + +using namespace std; + +TEST(GroupBarcodesUniq, should_return_same_group_barcodes) { + //given + Receipt receipt; + std::vector barcodesAndAmount = {{"001", 1}, + {"002", 4}, + {"003", 2}, + }; + + //when + std::vector barcodeAndAmountResult = receipt.GroupBarcodes(barcodesAndAmount); + + //then + ASSERT_EQ(3, barcodeAndAmountResult.size()); +} + +TEST(GroupBarcodesNotUniq, should_return_two_barcodes) { + //given + Receipt receipt; + std::vector barcodesAndAmount = {{"001", 1}, + {"002", 4}, + {"002", 2}, + }; + + //when + std::vector barcodeAndAmountResult = receipt.GroupBarcodes(barcodesAndAmount); + + //then + ASSERT_EQ(2, barcodeAndAmountResult.size()); +} \ No newline at end of file diff --git a/Test/ParseBarcodesTest.cpp b/Test/ParseBarcodesTest.cpp new file mode 100644 index 0000000000000000000000000000000000000000..7e2af6454f5b6003b425ba1e9618554fb0bc8883 --- /dev/null +++ b/Test/ParseBarcodesTest.cpp @@ -0,0 +1,41 @@ +#include +#include +#include +#include +#include +#include +#include "../include/common.h" +#include "../include/Receipt.h" + +using namespace std; + +TEST(ParseBarcodesWithThree, should_return_three_validate_barcodes) { + //given + Receipt receipt; + std::vector selectedbarcodes = {"001-1", + "002-2", + "003-2", + }; + + //when + std::vector barcodesAndAmountVector = receipt.ParseBarcodes(selectedbarcodes); + + //then + ASSERT_EQ(3, barcodesAndAmountVector.size()); +} + +TEST(ParseBarcodesWithFour, should_return_four_validate_barcodes) { + //given + Receipt receipt; + std::vector selectedbarcodes = {"001-1", + "002-2", + "003-2", + "003-2", + }; + + //when + std::vector barcodesAndAmountVector = receipt.ParseBarcodes(selectedbarcodes); + + //then + ASSERT_EQ(4, barcodesAndAmountVector.size()); +} \ No newline at end of file diff --git a/Test/PrintReceiptTest.cpp b/Test/PrintReceiptTest.cpp new file mode 100644 index 0000000000000000000000000000000000000000..c3f1681182245a5e5a0dc779fe58092c58eb920f --- /dev/null +++ b/Test/PrintReceiptTest.cpp @@ -0,0 +1,71 @@ +#include +#include +#include +#include +#include +#include +#include "../include/common.h" +#include "../include/Receipt.h" + +using namespace std; + +TEST(PrintReceiptWithQualifiedProduct, should_return_right_receipt_with_110_total_price) { + //given + Receipt receipt; + std::vector selectedbarcodes = {"001-1", + "002-2", + "003-2", + }; + + ProductsHash productsHash = {{"001", Product(string("product1"), 10)}, + {"002", Product(string("product2"), 20)}, + {"003", Product(string("product3"), 30)}, + }; + + //when + string receiptContent = receipt.PrintReceipt(selectedbarcodes, productsHash); + + //then + ASSERT_EQ("Receipt\n-------\nName: product3, Amount: 2, Price: 30.000000, Total: 60.000000\nName: product2, Amount: 2, Price: 20.000000, Total: 40.000000\nName: product1, Amount: 1, Price: 10.000000, Total: 10.000000\n-------\nTotal: 110.000000\n", receiptContent); +} + +TEST(PrintReceiptWithReceiptListError, should_return_barcide_cannot_be_recognized) { + //given + Receipt receipt; + std::vector selectedbarcodes = {"001-", + "002-2", + "003-2", + }; + + ProductsHash productsHash = {{"001", Product(string("product1"), 10)}, + {"002", Product(string("product2"), 20)}, + {"003", Product(string("product3"), 30)}, + }; + + //when + string receiptContent = receipt.PrintReceipt(selectedbarcodes, productsHash); + + //then + ASSERT_EQ("ERROR\n-------\nThe barcode cannot be recognized\n", receiptContent); +} + + +TEST(PrintReceiptWithReceiptProductError, should_return_product_cnnot_be_found) { + //given + Receipt receipt; + std::vector selectedbarcodes = {"001-1", + "004-2", + "005-2", + }; + + ProductsHash productsHash = {{"001", Product(string("product1"), 10)}, + {"002", Product(string("product2"), 20)}, + {"003", Product(string("product3"), 30)}, + }; + + //when + string receiptContent = receipt.PrintReceipt(selectedbarcodes, productsHash); + + //then + ASSERT_EQ("ERROR\n-------\nThe product cannot be found: 004\n", receiptContent); +} \ No newline at end of file diff --git a/Test/ValidateBarcodeTest.cpp b/Test/ValidateBarcodeTest.cpp new file mode 100644 index 0000000000000000000000000000000000000000..a81c41cb6e01a306c129028095d5ddd79c4edf49 --- /dev/null +++ b/Test/ValidateBarcodeTest.cpp @@ -0,0 +1,60 @@ +#include +#include +#include +#include +#include +#include +#include "../include/common.h" +#include "../include/Receipt.h" + +using namespace std; + +TEST(ValidateBarcodesOk, should_return_ok_for_validate_barcodes) { + //given + Receipt receipt; + std::vector selectedbarcodes = {"001-1", "003-2"}; + + ProductsHash productsHash = {{"001", Product(string("product1"), 1.1)}, + {"002", Product(string("product2"), 1.2)}, + {"003", Product(string("product3"), 1.3)}, + }; + + //when + ValidationResultS validationResult = receipt.ValidateBarcodes(selectedbarcodes, productsHash); + + //then + ASSERT_EQ(VALID_OK, validationResult.error); +} + +TEST(ValidateBarcodesList, should_return_ok_for_invalid_list) { + //given + Receipt receipt; + std::vector selectedbarcodes = {"001-", "003-2"}; + + ProductsHash productsHash = {{"001", Product(string("product1"), 1.1)}, + {"002", Product(string("product2"), 1.2)}, + }; + + //when + ValidationResultS validationResult = receipt.ValidateBarcodes(selectedbarcodes, productsHash); + + //then + ASSERT_EQ(ERROR_LIST, validationResult.error); +} + +TEST(ValidateBarcodesProduct, should_return_ok_for_invalid_Product) { + //given + Receipt receipt; + std::vector selectedbarcodes = {"001-2", "003-2"}; + + ProductsHash productsHash = {{"001", Product(string("product1"), 1.1)}, + {"002", Product(string("product2"), 1.2)}, + }; + + //when + ValidationResultS validationResult = receipt.ValidateBarcodes(selectedbarcodes, productsHash); + + //then + ASSERT_EQ(ERROR_PRODUCT, validationResult.error); + ASSERT_EQ("003", validationResult.barcode); +} \ No newline at end of file diff --git a/TestRun b/TestRun new file mode 100755 index 0000000000000000000000000000000000000000..c5919eda9e173618845bcc4785d1a89b650bd80c Binary files /dev/null and b/TestRun differ diff --git a/include/Receipt.h b/include/Receipt.h new file mode 100644 index 0000000000000000000000000000000000000000..7e52a549fc9c66984482eaaa43cf3acb17464845 --- /dev/null +++ b/include/Receipt.h @@ -0,0 +1,32 @@ +#ifndef RECEIPT_H +#define RECEIPT_H + +#include +#include +#include + +class Receipt { + private: + std::string receiptContent; + struct ReceiptWithPrice; + + public: + ReceiptWithTotalPriceS CreateReceipt(std::vector gourpedBarcodes, + ProductsHash productsHash); + std::string CreateValidReceipt(std::vector selectedBarcodes, + ProductsHash productsHash); + std::string FormatReceipt(ReceiptWithTotalPriceS receiptWithTotalPrice); + + std::vector ParseBarcodes(std::vector selectedBarcodes); + std::vector GroupBarcodes(std::vector barcodesAndAmount); + + ValidationResultS ValidateBarcodes(std::vector selectedBarcodes, + ProductsHash products); + + std::string CreateErrorReceipt(ValidationResultS validResult); + + std::string PrintReceipt(std::vector selectedBarcodes, ProductsHash productsHash); +}; + + +#endif //RECEIPT_H \ No newline at end of file diff --git a/include/common.h b/include/common.h new file mode 100644 index 0000000000000000000000000000000000000000..8ae7f76d10866ad118f65185aa5e5331a090cefc --- /dev/null +++ b/include/common.h @@ -0,0 +1,46 @@ +#ifndef COMMON_H +#define COMMON_H + +#include +#include +#include +#include + +#define VALID_OK 0 +#define ERROR_LIST 1 +#define ERROR_PRODUCT 2 + +using namespace std; + +typedef struct Product{ + std::string name; + double price; + Product(){} + Product(std::string name, double price) :name(name), price(price){} +}ProductS; + +typedef struct ProductAndAmount{ + ProductS product; + int amount; + double totalPrice; +}ProductAndAmountS; + +typedef struct ReceiptWithTotalPrice{ + std::vector productAndAmounts; + double receiptTotalPrice; +}ReceiptWithTotalPriceS; + +typedef std::map ProductsHash; + +typedef struct BarcodesAndAmount +{ + std::string barcode; + int amount; +}BarcodesAndAmountS; + +typedef struct ValidationResult{ + std::string barcode; + int error; +}ValidationResultS; + +#endif //COMMON_H \ No newline at end of file diff --git a/source/Receipt.cpp b/source/Receipt.cpp new file mode 100644 index 0000000000000000000000000000000000000000..086a326220d7311e002004a70400c75cb378a878 --- /dev/null +++ b/source/Receipt.cpp @@ -0,0 +1,205 @@ +#include +#include +#include +#include +#include +#include + +#include "../include/common.h" +#include "../include/Receipt.h" + +using namespace std; + +vector split(const string& str, const string& delim) { + vector res; + if("" == str) return res; + char * strs = new char[str.length() + 1] ; + strcpy(strs, str.c_str()); + + char * d = new char[delim.length() + 1]; + strcpy(d, delim.c_str()); + + char *p = strtok(strs, d); + while(p) { + string s = p; + res.push_back(s); + p = strtok(NULL, d); + } + + return res; +} + +ReceiptWithTotalPriceS Receipt::CreateReceipt(std::vector gourpedBarcodes, + ProductsHash productsHash) +{ + ReceiptWithTotalPriceS receiptWithTotalPrice; + double receiptTotalPrice = 0; + + for (std::vector::iterator iter = gourpedBarcodes.begin(); iter != gourpedBarcodes.end(); iter++) + { + ProductsHash::iterator productIterator = productsHash.find((*iter).barcode); + if(productIterator != productsHash.end()) { + ProductAndAmountS productAndAmount; + productAndAmount.product.name = productIterator->second.name; + productAndAmount.product.price = productIterator->second.price; + productAndAmount.amount = (*iter).amount; + productAndAmount.totalPrice = (*iter).amount * productIterator->second.price; + receiptTotalPrice += productAndAmount.totalPrice; + receiptWithTotalPrice.productAndAmounts.push_back(productAndAmount); + } + } + receiptWithTotalPrice.receiptTotalPrice = receiptTotalPrice; + + return receiptWithTotalPrice; +} + +std::string Receipt::CreateValidReceipt(std::vector selectedbarcodes, + ProductsHash products) +{ + vector barcodesAndAmountVector = ParseBarcodes(selectedbarcodes); + vector groupedBarcodes = GroupBarcodes(barcodesAndAmountVector); + ReceiptWithTotalPriceS receiptWithTotalPrice = CreateReceipt(groupedBarcodes, products); + string receiptContent = FormatReceipt(receiptWithTotalPrice); + + return receiptContent; +} + +std::string Receipt::FormatReceipt(ReceiptWithTotalPriceS receiptWithTotalPrice) +{ + string receiptContent = "Receipt\n-------\n"; + for (std::vector::iterator iter = receiptWithTotalPrice.productAndAmounts.begin(); + iter != receiptWithTotalPrice.productAndAmounts.end(); iter++) + { + receiptContent += "Name: "; + receiptContent += (*iter).product.name; + receiptContent += ", Amount: "; + receiptContent += to_string((*iter).amount); + receiptContent += ", Price: "; + receiptContent += to_string((*iter).product.price); + receiptContent += ", Total: "; + receiptContent += to_string((*iter).totalPrice); + receiptContent += "\n"; + } + receiptContent += "-------\nTotal: "; + receiptContent += to_string(receiptWithTotalPrice.receiptTotalPrice); + receiptContent += "\n"; + + return receiptContent; +} + +std::vector Receipt::ParseBarcodes(std::vector selectedbarcodes) +{ + vector barcodesAndAmountVector; + for (vector::iterator iter = selectedbarcodes.begin(); iter != selectedbarcodes.end(); iter++) + { + vector vecString = split(*iter, "-"); + + BarcodesAndAmountS barcodesAndAmount; + barcodesAndAmount.barcode = vecString[0]; + barcodesAndAmount.amount = std::stoi(vecString[1]); + barcodesAndAmountVector.push_back(barcodesAndAmount); + } + + return barcodesAndAmountVector; +} + +bool operator<(const BarcodesAndAmountS &barcodeA, const BarcodesAndAmountS &barcodeB) +{ + return barcodeA.barcode > barcodeB.barcode; +} + +std::vector Receipt::GroupBarcodes(std::vector barcodesAndAmount) +{ + vector uniqBarcodesAndAmount; + std::sort(barcodesAndAmount.begin(), barcodesAndAmount.end()); + string currentBarcode = ""; + int currentAmount = 0; + for (std::vector::iterator iter = barcodesAndAmount.begin(); iter != barcodesAndAmount.end(); iter++) + { + if(currentBarcode.compare((*iter).barcode) == 0) { + currentAmount += (*iter).amount; + } else { + if(currentBarcode.compare("") != 0) { + BarcodesAndAmountS barcodesAndAmount; + barcodesAndAmount.barcode = currentBarcode; + barcodesAndAmount.amount = currentAmount; + uniqBarcodesAndAmount.push_back(barcodesAndAmount); + } + currentBarcode = (*iter).barcode; + currentAmount = (*iter).amount; + } + } + + if(currentBarcode.compare("") != 0) { + BarcodesAndAmountS barcodesAndAmount; + barcodesAndAmount.barcode = currentBarcode; + barcodesAndAmount.amount = currentAmount; + uniqBarcodesAndAmount.push_back(barcodesAndAmount); + } + + return uniqBarcodesAndAmount; +} + +ValidationResultS Receipt::ValidateBarcodes(std::vector selectedbarcodes, + ProductsHash productsHash) +{ + vector::iterator iter; + ValidationResultS validResult; + validResult.error = VALID_OK; + for (vector::iterator iter = selectedbarcodes.begin(); iter != selectedbarcodes.end(); iter++) + { + vector vecString = split(*iter, "-"); + if (vecString.size() != 2) { + validResult.error = ERROR_LIST; + break; + } + int count = std::stoi(vecString[1]); + if (count <= 0) { + validResult.error = ERROR_LIST; + break; + } + + map::iterator pIter; + + if(productsHash.count(vecString[0]) <= 0){ + validResult.error = ERROR_PRODUCT; + validResult.barcode = vecString[0]; + break; + } + } + + return validResult; +} + +std::string Receipt::CreateErrorReceipt(ValidationResultS validResult) +{ + std::string receiptContent = ""; + + switch(validResult.error){ + case ERROR_LIST: + receiptContent = std::string("ERROR\n-------\nThe barcode cannot be recognized\n"); + break; + case ERROR_PRODUCT: + + receiptContent = std::string("ERROR\n-------\nThe product cannot be found: " + validResult.barcode + "\n"); + break; + default: + break; + }; + + return receiptContent; +} + +std::string Receipt::PrintReceipt(std::vector selectedBarcodes, ProductsHash productsHash) +{ + string receiptContent; + ValidationResultS validResult = ValidateBarcodes(selectedBarcodes, productsHash); + + if(validResult.error != VALID_OK) { + receiptContent = CreateErrorReceipt(validResult); + } else { + receiptContent = CreateValidReceipt(selectedBarcodes, productsHash); + } + + return receiptContent; +} \ No newline at end of file