From 7baeb4d6e4b5fe49d9b27644d046636466360946 Mon Sep 17 00:00:00 2001 From: Nicolas Svirchevsky Date: Mon, 25 Apr 2016 15:56:42 +0200 Subject: [PATCH 1/9] Documents nf-525 --- .../fr/pasteque/client/models/Address.java | 13 ++++++ .../fr/pasteque/client/models/Company.java | 15 +++++++ .../client/models/document/Cashing.java | 20 +++++++++ .../client/models/document/Customer.java | 15 +++++++ .../client/models/document/Invoice.java | 15 +++++++ .../client/models/document/Payment.java | 25 +++++++++++ .../client/models/document/Quantity.java | 11 +++++ .../client/models/document/Ticket.java | 41 +++++++++++++++++++ .../client/models/document/TicketLine.java | 32 +++++++++++++++ 9 files changed, 187 insertions(+) create mode 100644 app/src/main/java/fr/pasteque/client/models/Address.java create mode 100644 app/src/main/java/fr/pasteque/client/models/Company.java create mode 100644 app/src/main/java/fr/pasteque/client/models/document/Cashing.java create mode 100644 app/src/main/java/fr/pasteque/client/models/document/Customer.java create mode 100644 app/src/main/java/fr/pasteque/client/models/document/Invoice.java create mode 100644 app/src/main/java/fr/pasteque/client/models/document/Payment.java create mode 100644 app/src/main/java/fr/pasteque/client/models/document/Quantity.java create mode 100644 app/src/main/java/fr/pasteque/client/models/document/Ticket.java create mode 100644 app/src/main/java/fr/pasteque/client/models/document/TicketLine.java diff --git a/app/src/main/java/fr/pasteque/client/models/Address.java b/app/src/main/java/fr/pasteque/client/models/Address.java new file mode 100644 index 00000000..3856b543 --- /dev/null +++ b/app/src/main/java/fr/pasteque/client/models/Address.java @@ -0,0 +1,13 @@ +package fr.pasteque.client.models; + +/** + * Created by svirch_n on 25/04/16 + * Last edited at 15:39. + */ +public class Address { + + public String address; + public String postCode; + public String country; + public String city; +} diff --git a/app/src/main/java/fr/pasteque/client/models/Company.java b/app/src/main/java/fr/pasteque/client/models/Company.java new file mode 100644 index 00000000..f73abbe8 --- /dev/null +++ b/app/src/main/java/fr/pasteque/client/models/Company.java @@ -0,0 +1,15 @@ +package fr.pasteque.client.models; + +/** + * Created by svirch_n on 25/04/16 + * Last edited at 15:40. + */ +public class Company { + + public String name; + public Address address; + public String siret; + public String naf; + public String tvaNumber; + +} diff --git a/app/src/main/java/fr/pasteque/client/models/document/Cashing.java b/app/src/main/java/fr/pasteque/client/models/document/Cashing.java new file mode 100644 index 00000000..8df07ad0 --- /dev/null +++ b/app/src/main/java/fr/pasteque/client/models/document/Cashing.java @@ -0,0 +1,20 @@ +package fr.pasteque.client.models.document; + +/** + * Created by svirch_n on 25/04/16 + * This class is made from the NF-525 convention + * A cashing is a tickeline sum of TVA + * Last edited at 15:03. + */ +public class Cashing { + + public String id; + public String documentId; + public int htSum; + public String tvaCode; + public int tvaRate; + public int tvaSum; + public int discountSum; + public int ttcSum; + +} diff --git a/app/src/main/java/fr/pasteque/client/models/document/Customer.java b/app/src/main/java/fr/pasteque/client/models/document/Customer.java new file mode 100644 index 00000000..f22c7452 --- /dev/null +++ b/app/src/main/java/fr/pasteque/client/models/document/Customer.java @@ -0,0 +1,15 @@ +package fr.pasteque.client.models.document; + +/** + * Created by svirch_n on 25/04/16 + * This class is made from the NF-525 convention + * Last edited at 15:27. + */ +public class Customer { + + public String id; + public String documentId; + //public int lineNumber; + public String customerId; + +} diff --git a/app/src/main/java/fr/pasteque/client/models/document/Invoice.java b/app/src/main/java/fr/pasteque/client/models/document/Invoice.java new file mode 100644 index 00000000..7cbad29d --- /dev/null +++ b/app/src/main/java/fr/pasteque/client/models/document/Invoice.java @@ -0,0 +1,15 @@ +package fr.pasteque.client.models.document; + +import fr.pasteque.client.models.Company; + +/** + * Created by svirch_n on 25/04/16 + * This class is made from the NF-525 convention + * Last edited at 15:38. + */ +public class Invoice extends Ticket { + + public String id; + public String contactName; + public Company company; +} diff --git a/app/src/main/java/fr/pasteque/client/models/document/Payment.java b/app/src/main/java/fr/pasteque/client/models/document/Payment.java new file mode 100644 index 00000000..1d86375c --- /dev/null +++ b/app/src/main/java/fr/pasteque/client/models/document/Payment.java @@ -0,0 +1,25 @@ +package fr.pasteque.client.models.document; + +/** + * Created by svirch_n on 25/04/16 + * This class is made from the NF-525 convention + * Last edited at 15:34. + */ +public class Payment { + + public String id; + public String documentId; + public String paymentType; + public String paymentCode; + public String paymentName; + public String sum; + public String operationType; + //public String userCode; + public String date; + public String profitCenter; + public String cashRegisterCode; + public String cashierCode; + public String operatorCode; + public int quantity; + +} diff --git a/app/src/main/java/fr/pasteque/client/models/document/Quantity.java b/app/src/main/java/fr/pasteque/client/models/document/Quantity.java new file mode 100644 index 00000000..99aa7030 --- /dev/null +++ b/app/src/main/java/fr/pasteque/client/models/document/Quantity.java @@ -0,0 +1,11 @@ +package fr.pasteque.client.models.document; + +/** + * Created by svirch_n on 25/04/16 + * Last edited at 12:38. + */ +public class Quantity { + + public int quantity; + +} diff --git a/app/src/main/java/fr/pasteque/client/models/document/Ticket.java b/app/src/main/java/fr/pasteque/client/models/document/Ticket.java new file mode 100644 index 00000000..91a1ff9d --- /dev/null +++ b/app/src/main/java/fr/pasteque/client/models/document/Ticket.java @@ -0,0 +1,41 @@ +package fr.pasteque.client.models.document; + +import fr.pasteque.client.models.Company; + +import java.util.List; + +/** + * Created by svirch_n on 25/04/16 + * This class is made from the NF-525 convention + * Last edited at 12:17. + */ +public class Ticket { + + public String id; + public String documentId; + public String softwareVersion; + public int impressionNumber; + public Company innerCompanyName; + public String cashierCode; + public String cashierName; + public String operatorCode; + public String operatorName; + public String cashRegisterCode; + public int clientNumber; + //AAAAMMJJHHmmss + public String date; + public String operationType; + public String documentType; + public String ticketLineNumber; + + protected List ticketLines; + + public List cashings; + + public int htSum; + public int ttcSum; + + public Customer customer; + + public List payments; +} diff --git a/app/src/main/java/fr/pasteque/client/models/document/TicketLine.java b/app/src/main/java/fr/pasteque/client/models/document/TicketLine.java new file mode 100644 index 00000000..cd79189f --- /dev/null +++ b/app/src/main/java/fr/pasteque/client/models/document/TicketLine.java @@ -0,0 +1,32 @@ +package fr.pasteque.client.models.document; + +/** + * Created by svirch_n on 25/04/16 + * Last edited at 12:29. + */ +public class TicketLine { + + public String id; + public String documentId; + public int lineNumber; + //public String dataSource; + public String productName; + public Quantity quantity; + public String tvaCode; + public int tvaRate; + public int htValue; + public int ttcValue; + public String discountCode; + public int discountRate; + public int discountValue; + public int discountSum; + public int htSum; + public int ttcSum; + public String operationType; + //public String userCode; + public String date; + //public String profitCenter; + public String cashRegisterCode; + public String cashierCode; + public String operatorCode; +} -- GitLab From abded5f01a9a817e32099f9b36b99929ddd32ce6 Mon Sep 17 00:00:00 2001 From: Nicolas Svirchevsky Date: Tue, 26 Apr 2016 10:10:54 +0200 Subject: [PATCH 2/9] Pdf creation from a Pdf view --- .../client/PdfCreatorActivityTest.java | 27 +++++++++ app/src/main/AndroidManifest.xml | 4 ++ .../client/activities/PdfCreatorActivity.java | 22 +++++++ .../utils/CouldNotCreatePdfException.java | 12 ++++ .../fr/pasteque/client/utils/PdfCreator.java | 60 +++++++++++++++++++ .../java/fr/pasteque/client/widgets/Pdf.java | 36 +++++++++++ app/src/main/res/layout/company.xml | 24 ++++++++ app/src/main/res/layout/invoice.xml | 8 +++ .../main/res/layout/pdf_invoice_viewer.xml | 13 ++++ 9 files changed, 206 insertions(+) create mode 100644 app/src/androidTest/java/fr/pasteque/client/PdfCreatorActivityTest.java create mode 100644 app/src/main/java/fr/pasteque/client/activities/PdfCreatorActivity.java create mode 100644 app/src/main/java/fr/pasteque/client/utils/CouldNotCreatePdfException.java create mode 100644 app/src/main/java/fr/pasteque/client/utils/PdfCreator.java create mode 100644 app/src/main/java/fr/pasteque/client/widgets/Pdf.java create mode 100644 app/src/main/res/layout/company.xml create mode 100644 app/src/main/res/layout/invoice.xml create mode 100644 app/src/main/res/layout/pdf_invoice_viewer.xml diff --git a/app/src/androidTest/java/fr/pasteque/client/PdfCreatorActivityTest.java b/app/src/androidTest/java/fr/pasteque/client/PdfCreatorActivityTest.java new file mode 100644 index 00000000..702f918c --- /dev/null +++ b/app/src/androidTest/java/fr/pasteque/client/PdfCreatorActivityTest.java @@ -0,0 +1,27 @@ +package fr.pasteque.client; + +import android.test.ActivityInstrumentationTestCase2; +import android.test.UiThreadTest; +import android.view.View; +import fr.pasteque.client.activities.PdfCreatorActivity; +import fr.pasteque.client.utils.PdfCreator; +import fr.pasteque.client.utils.file.InternalFile; +import fr.pasteque.client.widgets.Pdf; + +import java.io.FileOutputStream; + +/** + * Created by svirch_n on 25/04/16 + * Last edited at 16:48. + */ +public class PdfCreatorActivityTest extends ActivityInstrumentationTestCase2 { + public PdfCreatorActivityTest() { + super(PdfCreatorActivity.class); + } + + @UiThreadTest + public void testPdf() throws Exception { + final View view = getActivity().getView(); + PdfCreator.build((Pdf) view, new FileOutputStream(new InternalFile("aPdf.pdf"))); + } +} diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 3e97c989..66b4de7c 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -49,6 +49,10 @@ + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/invoice.xml b/app/src/main/res/layout/invoice.xml new file mode 100644 index 00000000..2919a692 --- /dev/null +++ b/app/src/main/res/layout/invoice.xml @@ -0,0 +1,8 @@ + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/pdf_invoice_viewer.xml b/app/src/main/res/layout/pdf_invoice_viewer.xml new file mode 100644 index 00000000..baf03a75 --- /dev/null +++ b/app/src/main/res/layout/pdf_invoice_viewer.xml @@ -0,0 +1,13 @@ + + + + + + + + + + \ No newline at end of file -- GitLab From 2cb634afbbe541fac1c606063a87e3ba456acaa2 Mon Sep 17 00:00:00 2001 From: Nicolas Svirchevsky Date: Tue, 26 Apr 2016 18:26:40 +0200 Subject: [PATCH 3/9] Pdf holds inner and outer company field --- .gitignore | 2 +- .../client/PdfCreatorActivityTest.java | 31 ++++-- app/src/main/AndroidManifest.xml | 16 +-- .../java/fr/pasteque/client/Pasteque.java | 13 +++ .../fr/pasteque/client/ReceiptSelect.java | 10 +- .../client/activities/PdfCreatorActivity.java | 52 ++++++++- .../DataSavable/AbstractJsonDataSavable.java | 8 +- .../fr/pasteque/client/models/Address.java | 23 +++- .../fr/pasteque/client/models/Company.java | 4 +- .../fr/pasteque/client/models/Customer.java | 11 ++ .../client/models/document/Invoice.java | 4 +- .../client/utils/PastequeConfiguration.java | 22 ++++ .../fr/pasteque/client/utils/PdfCreator.java | 60 ---------- .../pasteque/client/widgets/CompanyView.java | 104 ++++++++++++++++++ .../java/fr/pasteque/client/widgets/Pdf.java | 61 +++++++++- app/src/main/res/layout/company.xml | 24 ---- app/src/main/res/layout/invoice.xml | 28 ++++- app/src/main/res/layout/pdf_customer_logo.xml | 8 ++ .../main/res/layout/pdf_invoice_viewer.xml | 5 +- app/src/main/res/layout/pdf_item_line.xml | 34 ++++++ .../main/res/layout/pdf_text_item_line.xml | 4 + app/src/main/res/layout/pdf_text_line.xml | 6 + app/src/main/res/values-fr/strings.xml | 1 + app/src/main/res/values/strings.xml | 1 + 24 files changed, 411 insertions(+), 121 deletions(-) delete mode 100644 app/src/main/java/fr/pasteque/client/utils/PdfCreator.java create mode 100644 app/src/main/java/fr/pasteque/client/widgets/CompanyView.java delete mode 100644 app/src/main/res/layout/company.xml create mode 100644 app/src/main/res/layout/pdf_customer_logo.xml create mode 100644 app/src/main/res/layout/pdf_item_line.xml create mode 100644 app/src/main/res/layout/pdf_text_item_line.xml create mode 100644 app/src/main/res/layout/pdf_text_line.xml diff --git a/.gitignore b/.gitignore index 6914c101..ac7024a7 100644 --- a/.gitignore +++ b/.gitignore @@ -26,7 +26,7 @@ tests/local.properties app/build build -app/account.gradle +account.gradle app/keystore.properties app/keystore diff --git a/app/src/androidTest/java/fr/pasteque/client/PdfCreatorActivityTest.java b/app/src/androidTest/java/fr/pasteque/client/PdfCreatorActivityTest.java index 702f918c..79492262 100644 --- a/app/src/androidTest/java/fr/pasteque/client/PdfCreatorActivityTest.java +++ b/app/src/androidTest/java/fr/pasteque/client/PdfCreatorActivityTest.java @@ -1,14 +1,15 @@ package fr.pasteque.client; +import android.content.Intent; import android.test.ActivityInstrumentationTestCase2; -import android.test.UiThreadTest; -import android.view.View; import fr.pasteque.client.activities.PdfCreatorActivity; -import fr.pasteque.client.utils.PdfCreator; +import fr.pasteque.client.data.Data; +import fr.pasteque.client.models.Receipt; import fr.pasteque.client.utils.file.InternalFile; import fr.pasteque.client.widgets.Pdf; import java.io.FileOutputStream; +import java.util.List; /** * Created by svirch_n on 25/04/16 @@ -19,9 +20,25 @@ public class PdfCreatorActivityTest extends ActivityInstrumentationTestCase2 receiptList = Data.Receipt.getReceipts(null); + Intent intent = new Intent().putExtra(PdfCreatorActivity.TICKET_TAG, receiptList.get(0).getTicket()); + setActivityIntent(intent); + } + + public void testPdf() throws Throwable { + final Pdf pdf = getActivity().getPdf(); + runTestOnUiThread(new Runnable() { + @Override + public void run() { + try { + pdf.build(new FileOutputStream(new InternalFile("aPdf.pdf"))); + } catch (Exception e) { + fail(); + } + } + }); } } diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 66b4de7c..c9865b90 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -16,10 +16,7 @@ android:theme="@style/POSTechTheme"> - - - - + @@ -32,7 +29,12 @@ - + + + + + + - - + lines) { + LinearLayout content = (LinearLayout) findViewById(R.id.lines); + for (TicketLine each : lines) { + RelativeLayout layout = (RelativeLayout) getLayoutInflater().inflate(R.layout.pdf_item_line, null); + setText(layout, R.id.name, each.getProduct().getLabel()); + setText(layout, R.id.qtt, "x " + each.getQuantity()); + setText(layout, R.id.taxe, String.valueOf(each.getTotalTaxCost(each.getDiscountRate()))); + setText(layout, R.id.price, String.valueOf(each.getTotalIncTax())); + content.addView(layout); + } + } + + private void setText(RelativeLayout layout, int id, String text) { + ((TextView)layout.findViewById(id)).setText(text); } - public View getView() { - return findViewById(R.id.pdf); + public Pdf getPdf() { + return (Pdf) findViewById(R.id.pdf); } } diff --git a/app/src/main/java/fr/pasteque/client/data/DataSavable/AbstractJsonDataSavable.java b/app/src/main/java/fr/pasteque/client/data/DataSavable/AbstractJsonDataSavable.java index df31b1e8..6715619d 100644 --- a/app/src/main/java/fr/pasteque/client/data/DataSavable/AbstractJsonDataSavable.java +++ b/app/src/main/java/fr/pasteque/client/data/DataSavable/AbstractJsonDataSavable.java @@ -40,6 +40,12 @@ public abstract class AbstractJsonDataSavable extends AbstractDataSavable { @Override public void load(Context ctx) throws DataCorruptedException, IOError { + File file = this.file; + List result = getObjects(file); + this.recoverObjects(result); + } + + public List getObjects(File file) throws DataCorruptedException { int objectsNumber = getNumberOfObjects(); List classes = getClassList(); List result = new ArrayList<>(); @@ -60,7 +66,7 @@ public abstract class AbstractJsonDataSavable extends AbstractDataSavable { if (result.size() != getObjectList().size()) { throw newException(null, stringFile); } - this.recoverObjects(result); + return result; } @Override diff --git a/app/src/main/java/fr/pasteque/client/models/Address.java b/app/src/main/java/fr/pasteque/client/models/Address.java index 3856b543..374463b1 100644 --- a/app/src/main/java/fr/pasteque/client/models/Address.java +++ b/app/src/main/java/fr/pasteque/client/models/Address.java @@ -1,13 +1,26 @@ package fr.pasteque.client.models; +import java.io.Serializable; + /** * Created by svirch_n on 25/04/16 * Last edited at 15:39. */ -public class Address { +public class Address implements Serializable{ + + public String address = ""; + public String postCode = ""; + public String city = ""; + public String country = ""; + + public Address() { + + } - public String address; - public String postCode; - public String country; - public String city; + public Address(String address, String postCode, String city, String country) { + this.address = address; + this.postCode = postCode; + this.country = country; + this.city = city; + } } diff --git a/app/src/main/java/fr/pasteque/client/models/Company.java b/app/src/main/java/fr/pasteque/client/models/Company.java index f73abbe8..d649e1cf 100644 --- a/app/src/main/java/fr/pasteque/client/models/Company.java +++ b/app/src/main/java/fr/pasteque/client/models/Company.java @@ -1,10 +1,12 @@ package fr.pasteque.client.models; +import java.io.Serializable; + /** * Created by svirch_n on 25/04/16 * Last edited at 15:40. */ -public class Company { +public class Company implements Serializable { public String name; public Address address; diff --git a/app/src/main/java/fr/pasteque/client/models/Customer.java b/app/src/main/java/fr/pasteque/client/models/Customer.java index 8153c692..81e767cd 100644 --- a/app/src/main/java/fr/pasteque/client/models/Customer.java +++ b/app/src/main/java/fr/pasteque/client/models/Customer.java @@ -214,4 +214,15 @@ public class Customer implements Serializable { public boolean equals(Object o) { return (o instanceof Customer) && this.id.equals(((Customer)o).id); } + + public Company getCompany() { + Company result = new Company(); + result.address = new Address(); + result.name = this.name; + result.address.address = this.address1; + result.address.city = this.city; + result.address.country = this.country; + result.address.postCode = this.zipCode; + return result; + } } diff --git a/app/src/main/java/fr/pasteque/client/models/document/Invoice.java b/app/src/main/java/fr/pasteque/client/models/document/Invoice.java index 7cbad29d..af91948c 100644 --- a/app/src/main/java/fr/pasteque/client/models/document/Invoice.java +++ b/app/src/main/java/fr/pasteque/client/models/document/Invoice.java @@ -2,12 +2,14 @@ package fr.pasteque.client.models.document; import fr.pasteque.client.models.Company; +import java.io.Serializable; + /** * Created by svirch_n on 25/04/16 * This class is made from the NF-525 convention * Last edited at 15:38. */ -public class Invoice extends Ticket { +public class Invoice extends Ticket implements Serializable { public String id; public String contactName; diff --git a/app/src/main/java/fr/pasteque/client/utils/PastequeConfiguration.java b/app/src/main/java/fr/pasteque/client/utils/PastequeConfiguration.java index 0d64113c..817b10a7 100644 --- a/app/src/main/java/fr/pasteque/client/utils/PastequeConfiguration.java +++ b/app/src/main/java/fr/pasteque/client/utils/PastequeConfiguration.java @@ -36,6 +36,28 @@ public class PastequeConfiguration { return true; } + public String getCompanyName() { + return "SCIL"; + } + + public String getCompanyAdresse() { + return "19 Rue Nicolas Leblanc"; + } + + public String getCompanyPostCode() { + return "59000"; + } + + public String getCompanyCity() { + return "Lille"; + } + + public String getCompanyCountry() { + return "France"; + } + + + public static class PrinterDriver { public static final String STARMPOP = "StarMPop"; public static final String EPSON = "EPSON ePOS"; diff --git a/app/src/main/java/fr/pasteque/client/utils/PdfCreator.java b/app/src/main/java/fr/pasteque/client/utils/PdfCreator.java deleted file mode 100644 index bb4fb6dc..00000000 --- a/app/src/main/java/fr/pasteque/client/utils/PdfCreator.java +++ /dev/null @@ -1,60 +0,0 @@ -package fr.pasteque.client.utils; - -import android.annotation.TargetApi; -import android.graphics.pdf.PdfDocument; - -import static android.graphics.pdf.PdfDocument.Page; -import static android.graphics.pdf.PdfDocument.PageInfo; - -import android.os.Build; -import android.view.View; -import fr.pasteque.client.widgets.Pdf; - -import java.io.IOException; -import java.io.OutputStream; - -/** - * Created by svirch_n on 25/04/16 - * Creates a pdf from a view - * Last edited at 16:42. - */ -public class PdfCreator { - - public static final int PDF_WIDTH_DP = 1323; - public static final int PDF_HEIGHT_DP = 1870; - - @TargetApi(Build.VERSION_CODES.KITKAT) - public static PdfDocument build(Pdf view, OutputStream stream) throws CouldNotCreatePdfException { - // create a new document - PdfDocument document = new PdfDocument(); - - // crate a page description - PageInfo pageInfo = new PageInfo.Builder(PDF_WIDTH_DP, PDF_HEIGHT_DP, 1).create(); - - // start a page - Page page = document.startPage(pageInfo); - - view.layout(0, 0, view.getMeasuredWidth(), view.getMeasuredHeight()); - view.forceLayout(); - view.setDrawingCacheEnabled(true); - view.buildDrawingCache(true); - view.requestLayout(); - - view.draw(page.getCanvas()); - - // finish the page - document.finishPage(page); - - // write the document content - try { - document.writeTo(stream); - } catch (IOException e) { - throw new CouldNotCreatePdfException(e); - } - - // close the document - document.close(); - - return new PdfDocument(); - } -} diff --git a/app/src/main/java/fr/pasteque/client/widgets/CompanyView.java b/app/src/main/java/fr/pasteque/client/widgets/CompanyView.java new file mode 100644 index 00000000..6a6c39e5 --- /dev/null +++ b/app/src/main/java/fr/pasteque/client/widgets/CompanyView.java @@ -0,0 +1,104 @@ +package fr.pasteque.client.widgets; + +import android.annotation.TargetApi; +import android.content.Context; +import android.os.Build; +import android.util.AttributeSet; +import android.view.ViewGroup; +import android.widget.ImageView; +import android.widget.RelativeLayout; +import android.widget.TextView; +import fr.pasteque.client.R; +import fr.pasteque.client.models.Company; + +import java.util.HashMap; +import java.util.Map; + +/** + * Created by svirch_n on 26/04/16 + * Last edited at 12:06. + */ +public class CompanyView extends RelativeLayout { + + private static final String DEFAULT_TEXT = "N/A"; + private static final int PADDING = 10; + private static int name = 1; + private static int address = 2; + private static int city = 3; + private static int country = 4; + private final Map views = new HashMap<>(); + private ImageView logo; + + public CompanyView(Context context) { + super(context); + this.init(); + } + + public CompanyView(Context context, AttributeSet attrs) { + super(context, attrs); + this.init(); + } + + public CompanyView(Context context, AttributeSet attrs, int defStyleAttr) { + super(context, attrs, defStyleAttr); + this.init(); + } + + @TargetApi(Build.VERSION_CODES.LOLLIPOP) + public CompanyView(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) { + super(context, attrs, defStyleAttr, defStyleRes); + this.init(); + } + + private void init() { + setPadding(PADDING, PADDING, PADDING, PADDING); + int[] ids = {CompanyView.name, CompanyView.address, CompanyView.city, CompanyView.country}; + int above = 0; + for (int each: ids) { + TextView textView = (TextView) inflate(getContext(), R.layout.pdf_text_line, null); + textView.setId(each); + textView.setText(CompanyView.DEFAULT_TEXT); + LayoutParams layoutParams = new LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT); + if (above != 0) { + layoutParams.addRule(RelativeLayout.BELOW, above); + } + textView.setLayoutParams(layoutParams); + addView(textView); + views.put(each, textView); + above = each; + } + logo = (ImageView) inflate(getContext(), R.layout.pdf_customer_logo, null); + logo.setVisibility(INVISIBLE); + addView(logo); + } + + public void setCompany(Company company) { + showText(); + setText(name, company.name); + setText(address, company.address.address); + setText(city, company.address.city + " " + company.address.postCode); + setText(country, company.address.country); + } + + private void setText(int id, String text) { + views.get(id).setText(text); + } + + public void noCompany() { + showLogo(); + } + + private void showLogo() { + for (TextView each: views.values()) { + each.setVisibility(INVISIBLE); + } + logo.setVisibility(VISIBLE); + } + + private void showText() { + for (TextView each: views.values()) { + each.setVisibility(VISIBLE); + } + logo.setVisibility(INVISIBLE); + } +} diff --git a/app/src/main/java/fr/pasteque/client/widgets/Pdf.java b/app/src/main/java/fr/pasteque/client/widgets/Pdf.java index a8a56854..603f502b 100644 --- a/app/src/main/java/fr/pasteque/client/widgets/Pdf.java +++ b/app/src/main/java/fr/pasteque/client/widgets/Pdf.java @@ -2,16 +2,29 @@ package fr.pasteque.client.widgets; import android.annotation.TargetApi; import android.content.Context; +import android.graphics.pdf.PdfDocument; import android.os.Build; import android.util.AttributeSet; -import android.widget.LinearLayout; -import fr.pasteque.client.utils.PdfCreator; +import android.view.View; +import android.widget.RelativeLayout; +import fr.pasteque.client.utils.CouldNotCreatePdfException; + +import java.io.IOException; +import java.io.OutputStream; /** * Created by svirch_n on 26/04/16 * Last edited at 10:02. */ -public class Pdf extends LinearLayout { +public class Pdf extends RelativeLayout { + + /** + * 160 * 8.3 + * 160 * 11.7 + */ + public static final int PDF_WIDTH_DP = 1323; + public static final int PDF_HEIGHT_DP = 1870; + public Pdf(Context context) { super(context); } @@ -31,6 +44,46 @@ public class Pdf extends LinearLayout { @Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { - super.onMeasure(PdfCreator.PDF_WIDTH_DP, PdfCreator.PDF_HEIGHT_DP); + widthMeasureSpec = View.MeasureSpec.makeMeasureSpec(PDF_WIDTH_DP, MeasureSpec.EXACTLY); + heightMeasureSpec = View.MeasureSpec.makeMeasureSpec(PDF_HEIGHT_DP, MeasureSpec.EXACTLY); + super.onMeasure(widthMeasureSpec, heightMeasureSpec); + } + + @TargetApi(Build.VERSION_CODES.KITKAT) + public void build(OutputStream stream) throws CouldNotCreatePdfException { + prepareView(); + PdfDocument document = prepareDocument(); + writeDocument(stream, document); + } + + private void prepareView() { + this.layout(0, 0, this.getMeasuredWidth(), this.getMeasuredHeight()); + this.forceLayout(); + this.setDrawingCacheEnabled(true); + this.buildDrawingCache(true); + this.requestLayout(); + } + + @TargetApi(Build.VERSION_CODES.KITKAT) + private PdfDocument prepareDocument() { + PdfDocument document = new PdfDocument(); + PdfDocument.PageInfo pageInfo = new PdfDocument.PageInfo.Builder(this.getMeasuredWidth(), this.getMeasuredHeight(), 1).create(); + PdfDocument.Page page = document.startPage(pageInfo); + this.draw(page.getCanvas()); + document.finishPage(page); + return document; + } + + @TargetApi(Build.VERSION_CODES.KITKAT) + private void writeDocument(OutputStream stream, PdfDocument document) throws CouldNotCreatePdfException { + // write the document content + try { + document.writeTo(stream); + } catch (IOException e) { + throw new CouldNotCreatePdfException(e); + } + + // close the document + document.close(); } } diff --git a/app/src/main/res/layout/company.xml b/app/src/main/res/layout/company.xml deleted file mode 100644 index 63b82167..00000000 --- a/app/src/main/res/layout/company.xml +++ /dev/null @@ -1,24 +0,0 @@ - - - - - - - - - - - - \ No newline at end of file diff --git a/app/src/main/res/layout/invoice.xml b/app/src/main/res/layout/invoice.xml index 2919a692..59c02a87 100644 --- a/app/src/main/res/layout/invoice.xml +++ b/app/src/main/res/layout/invoice.xml @@ -1,8 +1,30 @@ + android:layout_height="match_parent" + android:layout_width="match_parent" + android:padding="10dp"> + + + + + + + + + + - \ No newline at end of file diff --git a/app/src/main/res/layout/pdf_customer_logo.xml b/app/src/main/res/layout/pdf_customer_logo.xml new file mode 100644 index 00000000..76e9363b --- /dev/null +++ b/app/src/main/res/layout/pdf_customer_logo.xml @@ -0,0 +1,8 @@ + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/pdf_invoice_viewer.xml b/app/src/main/res/layout/pdf_invoice_viewer.xml index baf03a75..7dab5e6e 100644 --- a/app/src/main/res/layout/pdf_invoice_viewer.xml +++ b/app/src/main/res/layout/pdf_invoice_viewer.xml @@ -1,8 +1,9 @@ + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:layout_gravity="center_horizontal"> diff --git a/app/src/main/res/layout/pdf_item_line.xml b/app/src/main/res/layout/pdf_item_line.xml new file mode 100644 index 00000000..ce388120 --- /dev/null +++ b/app/src/main/res/layout/pdf_item_line.xml @@ -0,0 +1,34 @@ + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/pdf_text_item_line.xml b/app/src/main/res/layout/pdf_text_item_line.xml new file mode 100644 index 00000000..1a63878b --- /dev/null +++ b/app/src/main/res/layout/pdf_text_item_line.xml @@ -0,0 +1,4 @@ + + \ No newline at end of file diff --git a/app/src/main/res/layout/pdf_text_line.xml b/app/src/main/res/layout/pdf_text_line.xml new file mode 100644 index 00000000..39e6e4bc --- /dev/null +++ b/app/src/main/res/layout/pdf_text_line.xml @@ -0,0 +1,6 @@ + + \ No newline at end of file diff --git a/app/src/main/res/values-fr/strings.xml b/app/src/main/res/values-fr/strings.xml index 5e59e1cc..4ccf4cec 100644 --- a/app/src/main/res/values-fr/strings.xml +++ b/app/src/main/res/values-fr/strings.xml @@ -329,5 +329,6 @@ Configuration avancée Rapport par mail Envoie des rapports d\'erreur par mail + Facture diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index c7a760dc..4c867f9f 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -343,5 +343,6 @@ Advanced configuration Mail reporting Enable mail reporting + Invoice -- GitLab From 5aec9b1c3c7e5fb726b62a5842fa192f90409d0d Mon Sep 17 00:00:00 2001 From: Nicolas Svirchevsky Date: Thu, 28 Apr 2016 16:43:03 +0200 Subject: [PATCH 4/9] Invoice contains Taxes and Totals --- .../client/PdfCreatorActivityTest.java | 3 +- app/src/main/AndroidManifest.xml | 12 ++- .../client/activities/PdfCreatorActivity.java | 75 ++++++++++++++----- .../fr/pasteque/client/models/Ticket.java | 23 +++++- .../client/widgets/{ => pdf}/Pdf.java | 2 +- .../pasteque/client/widgets/pdf/PdfRow.java | 72 ++++++++++++++++++ .../client/widgets/pdf/PdfTaxeRow.java | 39 ++++++++++ .../client/widgets/pdf/PdfTicketRow.java | 38 ++++++++++ .../client/widgets/pdf/PdfTotalRow.java | 41 ++++++++++ app/src/main/res/layout/invoice.xml | 24 +++--- app/src/main/res/layout/pdf_divider.xml | 6 ++ .../main/res/layout/pdf_invoice_viewer.xml | 9 ++- .../main/res/layout/pdf_text_item_line.xml | 4 - app/src/main/res/layout/pdf_text_line.xml | 3 +- 14 files changed, 303 insertions(+), 48 deletions(-) rename app/src/main/java/fr/pasteque/client/widgets/{ => pdf}/Pdf.java (98%) create mode 100644 app/src/main/java/fr/pasteque/client/widgets/pdf/PdfRow.java create mode 100644 app/src/main/java/fr/pasteque/client/widgets/pdf/PdfTaxeRow.java create mode 100644 app/src/main/java/fr/pasteque/client/widgets/pdf/PdfTicketRow.java create mode 100644 app/src/main/java/fr/pasteque/client/widgets/pdf/PdfTotalRow.java create mode 100644 app/src/main/res/layout/pdf_divider.xml delete mode 100644 app/src/main/res/layout/pdf_text_item_line.xml diff --git a/app/src/androidTest/java/fr/pasteque/client/PdfCreatorActivityTest.java b/app/src/androidTest/java/fr/pasteque/client/PdfCreatorActivityTest.java index 79492262..4d121989 100644 --- a/app/src/androidTest/java/fr/pasteque/client/PdfCreatorActivityTest.java +++ b/app/src/androidTest/java/fr/pasteque/client/PdfCreatorActivityTest.java @@ -6,7 +6,7 @@ import fr.pasteque.client.activities.PdfCreatorActivity; import fr.pasteque.client.data.Data; import fr.pasteque.client.models.Receipt; import fr.pasteque.client.utils.file.InternalFile; -import fr.pasteque.client.widgets.Pdf; +import fr.pasteque.client.widgets.pdf.Pdf; import java.io.FileOutputStream; import java.util.List; @@ -16,6 +16,7 @@ import java.util.List; * Last edited at 16:48. */ public class PdfCreatorActivityTest extends ActivityInstrumentationTestCase2 { + public PdfCreatorActivityTest() { super(PdfCreatorActivity.class); } diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index c9865b90..f3569f84 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -16,7 +16,10 @@ android:theme="@style/POSTechTheme"> - + + + + @@ -29,12 +32,7 @@ - - - - - - + taxeValue = ticket.getTaxes(); + Map excByTaxes = ticket.getExcByTaxes(); + for (Double taxe: taxeValue.keySet()) { + PdfTaxeRow row = new PdfTaxeRow(getApplicationContext(), content); + row.setTaxe(taxe, taxeValue.get(taxe), excByTaxes.get(taxe)); + } + } + + private void addDivider(TableLayout content) { + getLayoutInflater().inflate(R.layout.pdf_divider, content, true); + } + + private void addTaxesHeader(TableLayout content) { + PdfTaxeRow row = new PdfTaxeRow(getApplicationContext(), content); + TableLayout.LayoutParams params = (TableLayout.LayoutParams) row.getLayoutParams(); + params.setMargins(0, HEADER_PADDING, 0, HEADER_PADDING); + row.setHeader(); } private void fillLines(List lines) { - LinearLayout content = (LinearLayout) findViewById(R.id.lines); - for (TicketLine each : lines) { - RelativeLayout layout = (RelativeLayout) getLayoutInflater().inflate(R.layout.pdf_item_line, null); - setText(layout, R.id.name, each.getProduct().getLabel()); - setText(layout, R.id.qtt, "x " + each.getQuantity()); - setText(layout, R.id.taxe, String.valueOf(each.getTotalTaxCost(each.getDiscountRate()))); - setText(layout, R.id.price, String.valueOf(each.getTotalIncTax())); - content.addView(layout); + TableLayout content = (TableLayout) findViewById(R.id.ticket); + addLinesHeader(content); + addDivider(content); + for (TicketLine each: lines) { + PdfTicketRow row = new PdfTicketRow(getApplicationContext(), content); + row.setTicket(each); } } - private void setText(RelativeLayout layout, int id, String text) { - ((TextView)layout.findViewById(id)).setText(text); + private void addLinesHeader(TableLayout content) { + PdfTicketRow row = new PdfTicketRow(getApplicationContext(), content); + row.setHeader(); } public Pdf getPdf() { diff --git a/app/src/main/java/fr/pasteque/client/models/Ticket.java b/app/src/main/java/fr/pasteque/client/models/Ticket.java index c6662ddb..55e679de 100644 --- a/app/src/main/java/fr/pasteque/client/models/Ticket.java +++ b/app/src/main/java/fr/pasteque/client/models/Ticket.java @@ -325,7 +325,7 @@ public class Ticket implements Serializable { } public Map getTaxes() { - Map taxes = new HashMap(); + Map taxes = new TreeMap<>(); for (TicketLine l : this.lines) { double rate = l.getProduct().getTaxRate(); double amount = l.getTotalTaxCost(this.discountRate); @@ -337,6 +337,19 @@ public class Ticket implements Serializable { return taxes; } + public Map getExcByTaxes() { + Map taxes = new TreeMap(); + for (TicketLine l : this.lines) { + double rate = l.getProduct().getTaxRate(); + double amount = l.getTotalDiscPExcTax(); + if (taxes.containsKey(rate)) { + amount += taxes.get(rate); + } + taxes.put(rate, amount); + } + return taxes; + } + public String getTicketId() { return this.ticketId; } @@ -554,6 +567,14 @@ public class Ticket implements Serializable { _addTicketLine(refundLine); } + public double getTicketTax() { + double result = 0; + for (Double each : getTaxes().values()) { + result += each; + } + return result; + } + protected static class TicketInstance { public Ticket newTicket(String id, String label) { return new Ticket(id, label); diff --git a/app/src/main/java/fr/pasteque/client/widgets/Pdf.java b/app/src/main/java/fr/pasteque/client/widgets/pdf/Pdf.java similarity index 98% rename from app/src/main/java/fr/pasteque/client/widgets/Pdf.java rename to app/src/main/java/fr/pasteque/client/widgets/pdf/Pdf.java index 603f502b..e20ae223 100644 --- a/app/src/main/java/fr/pasteque/client/widgets/Pdf.java +++ b/app/src/main/java/fr/pasteque/client/widgets/pdf/Pdf.java @@ -1,4 +1,4 @@ -package fr.pasteque.client.widgets; +package fr.pasteque.client.widgets.pdf; import android.annotation.TargetApi; import android.content.Context; diff --git a/app/src/main/java/fr/pasteque/client/widgets/pdf/PdfRow.java b/app/src/main/java/fr/pasteque/client/widgets/pdf/PdfRow.java new file mode 100644 index 00000000..33b6e826 --- /dev/null +++ b/app/src/main/java/fr/pasteque/client/widgets/pdf/PdfRow.java @@ -0,0 +1,72 @@ +package fr.pasteque.client.widgets.pdf; + +import android.content.Context; +import android.graphics.drawable.Drawable; +import android.util.AttributeSet; +import android.view.Gravity; +import android.widget.LinearLayout; +import android.widget.TableLayout; +import android.widget.TableRow; +import android.widget.TextView; +import fr.pasteque.client.R; +import fr.pasteque.client.utils.CalculPrice; + +/** + * Created by svirch_n on 27/04/16 + * Last edited at 10:04. + */ +public abstract class PdfRow extends TableRow { + + static final int PADDING = 0; + static final int CHILD_PADDING = 10; + static final int ROUND = 2; + private int[] gravity = { + Gravity.LEFT, + Gravity.RIGHT, + Gravity.RIGHT, + Gravity.RIGHT + }; + + + public PdfRow(Context context, TableLayout root) { + super(context); + init(root); + } + + public PdfRow(Context context, AttributeSet attrs) { + super(context, attrs); + } + + public PdfRow(Context context) { + super(context); + } + + private void init(TableLayout root) { + if (root != null) { + TableLayout.LayoutParams rootParams = root.generateLayoutParams(null); + rootParams.setMargins(0, PADDING, 0, PADDING); + setLayoutParams(rootParams); + root.addView(this); + } + } + + protected void addElements(String[] elements) { + + for (int i = 0; i < elements.length; i++) { + if (elements[i] != null) { + TextView textView = (TextView) inflate(getContext(), R.layout.pdf_text_line, null); + LayoutParams params = (LayoutParams) this.generateDefaultLayoutParams(); + params.setMargins(CHILD_PADDING, CHILD_PADDING, CHILD_PADDING, CHILD_PADDING); + params.column = i; + textView.setLayoutParams(params); + textView.setText(elements[i]); + textView.setGravity(gravity[i]); + this.addView(textView); + } + } + } + + protected double round(Double number) { + return CalculPrice.round(number, ROUND); + } +} diff --git a/app/src/main/java/fr/pasteque/client/widgets/pdf/PdfTaxeRow.java b/app/src/main/java/fr/pasteque/client/widgets/pdf/PdfTaxeRow.java new file mode 100644 index 00000000..aa3a621d --- /dev/null +++ b/app/src/main/java/fr/pasteque/client/widgets/pdf/PdfTaxeRow.java @@ -0,0 +1,39 @@ +package fr.pasteque.client.widgets.pdf; + +import android.content.Context; +import android.widget.TableLayout; +import fr.pasteque.client.utils.CalculPrice; + +import java.text.DecimalFormat; + +/** + * Created by svirch_n on 28/04/16 + * Last edited at 15:56. + */ +public class PdfTaxeRow extends PdfRow { + + public PdfTaxeRow(Context context, TableLayout root) { + super(context, root); + } + + public void setHeader() { + String[] elements = { + "TVA ", + null, + "HT", + "Taxe", + }; + addElements(elements); + } + + public void setTaxe(Double taxe, Double taxeValue, Double excValue) { + DecimalFormat decimalFormat = new DecimalFormat("#.##"); + String[] elements = { + decimalFormat.format(taxe * 100) + "%", + null, + String.valueOf(round(excValue)), + String.valueOf(round(taxeValue)) + }; + addElements(elements); + } +} diff --git a/app/src/main/java/fr/pasteque/client/widgets/pdf/PdfTicketRow.java b/app/src/main/java/fr/pasteque/client/widgets/pdf/PdfTicketRow.java new file mode 100644 index 00000000..24431130 --- /dev/null +++ b/app/src/main/java/fr/pasteque/client/widgets/pdf/PdfTicketRow.java @@ -0,0 +1,38 @@ +package fr.pasteque.client.widgets.pdf; + +import android.content.Context; +import android.widget.TableLayout; +import fr.pasteque.client.models.TicketLine; +import fr.pasteque.client.utils.CalculPrice; + +/** + * Created by svirch_n on 28/04/16 + * Last edited at 15:25. + */ +public class PdfTicketRow extends PdfRow { + + public PdfTicketRow(Context context, TableLayout root) { + super(context, root); + } + + + public void setTicket(TicketLine ticketLine) { + String[] elements = { + ticketLine.getProduct().getLabel(), + "x " + ticketLine.getQuantity(), + String.valueOf(round(ticketLine.getProductIncTax())), + String.valueOf(round(ticketLine.getTotalIncTax())) + }; + addElements(elements); + } + + public void setHeader() { + String[] elements = { + "Product Name", + "Quantity", + "Unit TTC", + "Total TTC" + }; + addElements(elements); + } +} diff --git a/app/src/main/java/fr/pasteque/client/widgets/pdf/PdfTotalRow.java b/app/src/main/java/fr/pasteque/client/widgets/pdf/PdfTotalRow.java new file mode 100644 index 00000000..49fe5009 --- /dev/null +++ b/app/src/main/java/fr/pasteque/client/widgets/pdf/PdfTotalRow.java @@ -0,0 +1,41 @@ +package fr.pasteque.client.widgets.pdf; + +import android.content.Context; +import android.widget.TableLayout; +import fr.pasteque.client.models.Ticket; + +import java.text.DecimalFormat; + +/** + * Created by svirch_n on 28/04/16 + * Last edited at 16:32. + */ +public class PdfTotalRow extends PdfRow { + + + public PdfTotalRow(Context applicationContext, TableLayout content) { + super(applicationContext, content); + } + + + public void setTotal(Ticket total) { + DecimalFormat df = new DecimalFormat("#.00"); + String[] elements = { + null, + String.valueOf(df.format(round(total.getTicketPriceExcTax()))), + String.valueOf(df.format(round(total.getTicketTax()))), + String.valueOf(df.format(round(total.getTicketPrice()))) + }; + addElements(elements); + } + + public void setHeader() { + String[] elements = { + "Total ", + "HT", + "Taxe", + "TTC", + }; + addElements(elements); + } +} diff --git a/app/src/main/res/layout/invoice.xml b/app/src/main/res/layout/invoice.xml index 59c02a87..a097e015 100644 --- a/app/src/main/res/layout/invoice.xml +++ b/app/src/main/res/layout/invoice.xml @@ -1,9 +1,8 @@ - + - + + - - - \ No newline at end of file + \ No newline at end of file diff --git a/app/src/main/res/layout/pdf_divider.xml b/app/src/main/res/layout/pdf_divider.xml new file mode 100644 index 00000000..fd2c9ac2 --- /dev/null +++ b/app/src/main/res/layout/pdf_divider.xml @@ -0,0 +1,6 @@ + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/pdf_invoice_viewer.xml b/app/src/main/res/layout/pdf_invoice_viewer.xml index 7dab5e6e..97979a1b 100644 --- a/app/src/main/res/layout/pdf_invoice_viewer.xml +++ b/app/src/main/res/layout/pdf_invoice_viewer.xml @@ -5,10 +5,13 @@ android:layout_height="wrap_content" android:layout_gravity="center_horizontal"> - + - + - + + + \ No newline at end of file diff --git a/app/src/main/res/layout/pdf_text_item_line.xml b/app/src/main/res/layout/pdf_text_item_line.xml deleted file mode 100644 index 1a63878b..00000000 --- a/app/src/main/res/layout/pdf_text_item_line.xml +++ /dev/null @@ -1,4 +0,0 @@ - - \ No newline at end of file diff --git a/app/src/main/res/layout/pdf_text_line.xml b/app/src/main/res/layout/pdf_text_line.xml index 39e6e4bc..b946f06f 100644 --- a/app/src/main/res/layout/pdf_text_line.xml +++ b/app/src/main/res/layout/pdf_text_line.xml @@ -2,5 +2,6 @@ \ No newline at end of file -- GitLab From 4d596cdf2e623c73952170c63e7fe9c670ed1ee6 Mon Sep 17 00:00:00 2001 From: Nicolas Svirchevsky Date: Fri, 29 Apr 2016 11:19:51 +0200 Subject: [PATCH 5/9] Time and Date format is centralized --- app/src/main/java/fr/pasteque/client/Pasteque.java | 5 ++++- app/src/main/java/fr/pasteque/client/models/Ticket.java | 7 +++---- .../fr/pasteque/client/utils/PastequeConfiguration.java | 5 +++++ 3 files changed, 12 insertions(+), 5 deletions(-) diff --git a/app/src/main/java/fr/pasteque/client/Pasteque.java b/app/src/main/java/fr/pasteque/client/Pasteque.java index b0c51860..18477161 100644 --- a/app/src/main/java/fr/pasteque/client/Pasteque.java +++ b/app/src/main/java/fr/pasteque/client/Pasteque.java @@ -7,6 +7,7 @@ import android.widget.Toast; import fr.pasteque.client.drivers.DefaultDeviceManager; import fr.pasteque.client.models.Address; import fr.pasteque.client.models.Company; +import fr.pasteque.client.utils.Date; import fr.pasteque.client.utils.PastequeConfiguration; import java.util.ArrayList; @@ -132,5 +133,7 @@ public class Pasteque extends Application { } } - + public static Date now() { + return new Date(); + } } diff --git a/app/src/main/java/fr/pasteque/client/models/Ticket.java b/app/src/main/java/fr/pasteque/client/models/Ticket.java index 55e679de..1dcc072f 100644 --- a/app/src/main/java/fr/pasteque/client/models/Ticket.java +++ b/app/src/main/java/fr/pasteque/client/models/Ticket.java @@ -18,14 +18,14 @@ package fr.pasteque.client.models; import java.io.Serializable; -import java.text.SimpleDateFormat; import java.util.*; +import java.util.Date; import fr.pasteque.client.Configure; import fr.pasteque.client.Pasteque; import fr.pasteque.client.data.Data; import fr.pasteque.client.sync.TicketUpdater; -import fr.pasteque.client.utils.CalculPrice; +import fr.pasteque.client.utils.*; import org.json.JSONArray; import org.json.JSONException; import org.json.JSONObject; @@ -41,7 +41,6 @@ import android.util.Log; */ public class Ticket implements Serializable { - private static final String DATE_FORMAT = "HH:mm:ss"; private String id; // private String ticketId; private int articles; @@ -152,7 +151,7 @@ public class Ticket implements Serializable { if (this.label != null) { return label; } - return new SimpleDateFormat(DATE_FORMAT).format(creationTime); + return new fr.pasteque.client.utils.Date(creationTime).formatTime(); } public TariffArea getTariffArea() { diff --git a/app/src/main/java/fr/pasteque/client/utils/PastequeConfiguration.java b/app/src/main/java/fr/pasteque/client/utils/PastequeConfiguration.java index 817b10a7..79cbb865 100644 --- a/app/src/main/java/fr/pasteque/client/utils/PastequeConfiguration.java +++ b/app/src/main/java/fr/pasteque/client/utils/PastequeConfiguration.java @@ -4,6 +4,8 @@ import android.content.Context; import android.content.SharedPreferences; import android.preference.PreferenceManager; +import java.util.Locale; + /** * Created by svirch_n on 22/12/15. */ @@ -56,6 +58,9 @@ public class PastequeConfiguration { return "France"; } + public Locale getLocal() { + return Locale.FRANCE; + } public static class PrinterDriver { -- GitLab From bb15be0262a516f3d04bba45562b5c3d13ebbc31 Mon Sep 17 00:00:00 2001 From: Nicolas Svirchevsky Date: Fri, 29 Apr 2016 12:33:53 +0200 Subject: [PATCH 6/9] Pdf content is more legal, Pdf generation is padding free --- .../java/fr/pasteque/client/utils/Date.java | 46 +++++++++++++++ .../pasteque/client/widgets/CompanyView.java | 6 +- .../fr/pasteque/client/widgets/TodayDate.java | 47 +++++++++++++++ .../pasteque/client/widgets/pdf/PdfRow.java | 9 +++ .../client/widgets/pdf/PdfTaxeRow.java | 7 ++- .../client/widgets/pdf/PdfTicketRow.java | 24 ++++++-- .../client/widgets/pdf/PdfTotalRow.java | 4 ++ .../client/widgets/time/DateTimeView.java | 37 ++++++++++++ .../client/widgets/time/DateView.java | 20 +++++++ .../client/widgets/time/TimeView.java | 20 +++++++ app/src/main/res/layout/invoice.xml | 59 +++++++++++++++---- app/src/main/res/layout/pdf_text_line.xml | 2 +- 12 files changed, 259 insertions(+), 22 deletions(-) create mode 100644 app/src/main/java/fr/pasteque/client/utils/Date.java create mode 100644 app/src/main/java/fr/pasteque/client/widgets/TodayDate.java create mode 100644 app/src/main/java/fr/pasteque/client/widgets/time/DateTimeView.java create mode 100644 app/src/main/java/fr/pasteque/client/widgets/time/DateView.java create mode 100644 app/src/main/java/fr/pasteque/client/widgets/time/TimeView.java diff --git a/app/src/main/java/fr/pasteque/client/utils/Date.java b/app/src/main/java/fr/pasteque/client/utils/Date.java new file mode 100644 index 00000000..3d409906 --- /dev/null +++ b/app/src/main/java/fr/pasteque/client/utils/Date.java @@ -0,0 +1,46 @@ +package fr.pasteque.client.utils; + +import fr.pasteque.client.Pasteque; + +import java.io.Serializable; +import java.text.SimpleDateFormat; + +/** + * Created by svirch_n on 29/04/16 + * Last edited at 10:43. + */ +public class Date implements Serializable{ + + private final double date; + private static final String TIME_FORMAT = "HH:mm:ss"; + private static final String DATE_FORMAT = "MM/dd/yyyy"; + private static final String DATE_TIME_FORMAT = DATE_FORMAT + " " + TIME_FORMAT; + + + public Date(double date) { + this.date = date; + } + + public Date() { + this.date = new java.util.Date().getTime(); + } + + public String format(String formatDate) { + return new SimpleDateFormat(formatDate).format(date); + } + + public String formatTime() { + return format(TIME_FORMAT); + } + + public String formatDate() { + return format(DATE_FORMAT); + } + + public String formatDateTime() { + return format(DATE_TIME_FORMAT); + } + + + +} diff --git a/app/src/main/java/fr/pasteque/client/widgets/CompanyView.java b/app/src/main/java/fr/pasteque/client/widgets/CompanyView.java index 6a6c39e5..d0ae2e4b 100644 --- a/app/src/main/java/fr/pasteque/client/widgets/CompanyView.java +++ b/app/src/main/java/fr/pasteque/client/widgets/CompanyView.java @@ -21,7 +21,7 @@ import java.util.Map; public class CompanyView extends RelativeLayout { private static final String DEFAULT_TEXT = "N/A"; - private static final int PADDING = 10; + private static final int PADDING = 0; private static int name = 1; private static int address = 2; private static int city = 3; @@ -68,6 +68,9 @@ public class CompanyView extends RelativeLayout { above = each; } logo = (ImageView) inflate(getContext(), R.layout.pdf_customer_logo, null); + RelativeLayout.LayoutParams params = (LayoutParams) this.generateDefaultLayoutParams(); + params.addRule(CENTER_IN_PARENT, TRUE); + logo.setLayoutParams(params); logo.setVisibility(INVISIBLE); addView(logo); } @@ -93,6 +96,7 @@ public class CompanyView extends RelativeLayout { each.setVisibility(INVISIBLE); } logo.setVisibility(VISIBLE); + setText(name, "A PADDING TEXT"); } private void showText() { diff --git a/app/src/main/java/fr/pasteque/client/widgets/TodayDate.java b/app/src/main/java/fr/pasteque/client/widgets/TodayDate.java new file mode 100644 index 00000000..335f9b24 --- /dev/null +++ b/app/src/main/java/fr/pasteque/client/widgets/TodayDate.java @@ -0,0 +1,47 @@ +package fr.pasteque.client.widgets; + +import android.annotation.TargetApi; +import android.content.Context; +import android.os.Build; +import android.util.AttributeSet; +import android.widget.LinearLayout; +import android.widget.TextView; +import fr.pasteque.client.Pasteque; +import fr.pasteque.client.utils.Date; +import fr.pasteque.client.widgets.time.DateView; +import fr.pasteque.client.widgets.time.TimeView; + +/** + * Created by svirch_n on 29/04/16 + * Last edited at 10:39. + */ +public class TodayDate extends LinearLayout { + public TodayDate(Context context) { + super(context); + this.init(); + } + + public TodayDate(Context context, AttributeSet attrs) { + super(context, attrs); + this.init(); + } + + public TodayDate(Context context, AttributeSet attrs, int defStyleAttr) { + super(context, attrs, defStyleAttr); + this.init(); + } + + @TargetApi(Build.VERSION_CODES.LOLLIPOP) + public TodayDate(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) { + super(context, attrs, defStyleAttr, defStyleRes); + this.init(); + } + + public void init() { + setOrientation(VERTICAL); + Date date = Pasteque.now(); + new TimeView(this, "Time: ", date); + new DateView(this, "Date: ", date); + + } +} diff --git a/app/src/main/java/fr/pasteque/client/widgets/pdf/PdfRow.java b/app/src/main/java/fr/pasteque/client/widgets/pdf/PdfRow.java index 33b6e826..1a9d9907 100644 --- a/app/src/main/java/fr/pasteque/client/widgets/pdf/PdfRow.java +++ b/app/src/main/java/fr/pasteque/client/widgets/pdf/PdfRow.java @@ -11,6 +11,8 @@ import android.widget.TextView; import fr.pasteque.client.R; import fr.pasteque.client.utils.CalculPrice; +import java.text.DecimalFormat; + /** * Created by svirch_n on 27/04/16 * Last edited at 10:04. @@ -24,6 +26,8 @@ public abstract class PdfRow extends TableRow { Gravity.LEFT, Gravity.RIGHT, Gravity.RIGHT, + Gravity.RIGHT, + Gravity.RIGHT, Gravity.RIGHT }; @@ -69,4 +73,9 @@ public abstract class PdfRow extends TableRow { protected double round(Double number) { return CalculPrice.round(number, ROUND); } + + protected String formatTax(Double taxe) { + DecimalFormat decimalFormat = new DecimalFormat("#.##"); + return decimalFormat.format(taxe * 100) + "%"; + } } diff --git a/app/src/main/java/fr/pasteque/client/widgets/pdf/PdfTaxeRow.java b/app/src/main/java/fr/pasteque/client/widgets/pdf/PdfTaxeRow.java index aa3a621d..11fa9e1f 100644 --- a/app/src/main/java/fr/pasteque/client/widgets/pdf/PdfTaxeRow.java +++ b/app/src/main/java/fr/pasteque/client/widgets/pdf/PdfTaxeRow.java @@ -20,6 +20,8 @@ public class PdfTaxeRow extends PdfRow { String[] elements = { "TVA ", null, + null, + null, "HT", "Taxe", }; @@ -27,9 +29,10 @@ public class PdfTaxeRow extends PdfRow { } public void setTaxe(Double taxe, Double taxeValue, Double excValue) { - DecimalFormat decimalFormat = new DecimalFormat("#.##"); String[] elements = { - decimalFormat.format(taxe * 100) + "%", + formatTax(taxe), + null, + null, null, String.valueOf(round(excValue)), String.valueOf(round(taxeValue)) diff --git a/app/src/main/java/fr/pasteque/client/widgets/pdf/PdfTicketRow.java b/app/src/main/java/fr/pasteque/client/widgets/pdf/PdfTicketRow.java index 24431130..01dfb3ea 100644 --- a/app/src/main/java/fr/pasteque/client/widgets/pdf/PdfTicketRow.java +++ b/app/src/main/java/fr/pasteque/client/widgets/pdf/PdfTicketRow.java @@ -3,7 +3,8 @@ package fr.pasteque.client.widgets.pdf; import android.content.Context; import android.widget.TableLayout; import fr.pasteque.client.models.TicketLine; -import fr.pasteque.client.utils.CalculPrice; + +import java.text.DecimalFormat; /** * Created by svirch_n on 28/04/16 @@ -19,18 +20,31 @@ public class PdfTicketRow extends PdfRow { public void setTicket(TicketLine ticketLine) { String[] elements = { ticketLine.getProduct().getLabel(), - "x " + ticketLine.getQuantity(), - String.valueOf(round(ticketLine.getProductIncTax())), - String.valueOf(round(ticketLine.getTotalIncTax())) + "x " + formatQuantity(ticketLine.getQuantity()), + formatRound(ticketLine.getProductExcTax()), + formatTax(ticketLine.getDiscountRate()), + formatTax(ticketLine.getProduct().getTaxRate()), + formatRound(ticketLine.getTotalIncTax()) }; addElements(elements); } + private String formatRound(double value) { + return String.valueOf(round(value)); + } + + private String formatQuantity(double quantity) { + DecimalFormat decimalFormat = new DecimalFormat("#"); + return decimalFormat.format(quantity); + } + public void setHeader() { String[] elements = { "Product Name", "Quantity", - "Unit TTC", + "Unit HT", + "Discount", + "TVA", "Total TTC" }; addElements(elements); diff --git a/app/src/main/java/fr/pasteque/client/widgets/pdf/PdfTotalRow.java b/app/src/main/java/fr/pasteque/client/widgets/pdf/PdfTotalRow.java index 49fe5009..1d8ac127 100644 --- a/app/src/main/java/fr/pasteque/client/widgets/pdf/PdfTotalRow.java +++ b/app/src/main/java/fr/pasteque/client/widgets/pdf/PdfTotalRow.java @@ -21,6 +21,8 @@ public class PdfTotalRow extends PdfRow { public void setTotal(Ticket total) { DecimalFormat df = new DecimalFormat("#.00"); String[] elements = { + null, + null, null, String.valueOf(df.format(round(total.getTicketPriceExcTax()))), String.valueOf(df.format(round(total.getTicketTax()))), @@ -32,6 +34,8 @@ public class PdfTotalRow extends PdfRow { public void setHeader() { String[] elements = { "Total ", + null, + null, "HT", "Taxe", "TTC", diff --git a/app/src/main/java/fr/pasteque/client/widgets/time/DateTimeView.java b/app/src/main/java/fr/pasteque/client/widgets/time/DateTimeView.java new file mode 100644 index 00000000..15f7bbed --- /dev/null +++ b/app/src/main/java/fr/pasteque/client/widgets/time/DateTimeView.java @@ -0,0 +1,37 @@ +package fr.pasteque.client.widgets.time; + +import android.util.AttributeSet; +import android.widget.LinearLayout; +import android.widget.TextView; +import fr.pasteque.client.utils.Date; +import fr.pasteque.client.widgets.TodayDate; + +import static android.view.ViewGroup.LayoutParams.MATCH_PARENT; +import static android.view.ViewGroup.LayoutParams.WRAP_CONTENT; + +/** + * Created by svirch_n on 29/04/16 + * Last edited at 11:23. + */ +public abstract class DateTimeView extends TextView { + + private String preText; + private Date date; + + public DateTimeView(TodayDate todayDate, String preText, Date date) { + super(todayDate.getContext()); + this.preText = preText; + this.date = date; + this.init(todayDate); + } + + private void init(TodayDate root) { + LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(WRAP_CONTENT, WRAP_CONTENT); + setLayoutParams(params); + root.addView(this); + String text = preText + getTimeFormat(this.date); + setText(text); + } + + protected abstract String getTimeFormat(Date date); +} diff --git a/app/src/main/java/fr/pasteque/client/widgets/time/DateView.java b/app/src/main/java/fr/pasteque/client/widgets/time/DateView.java new file mode 100644 index 00000000..2cfe7bad --- /dev/null +++ b/app/src/main/java/fr/pasteque/client/widgets/time/DateView.java @@ -0,0 +1,20 @@ +package fr.pasteque.client.widgets.time; + +import fr.pasteque.client.utils.Date; +import fr.pasteque.client.widgets.TodayDate; + +/** + * Created by svirch_n on 29/04/16 + * Last edited at 11:28. + */ +public class DateView extends DateTimeView { + + public DateView(TodayDate todayDate, String preText, Date date) { + super(todayDate, preText, date); + } + + @Override + protected String getTimeFormat(Date date) { + return date.formatDate(); + } +} diff --git a/app/src/main/java/fr/pasteque/client/widgets/time/TimeView.java b/app/src/main/java/fr/pasteque/client/widgets/time/TimeView.java new file mode 100644 index 00000000..f3b0a0cf --- /dev/null +++ b/app/src/main/java/fr/pasteque/client/widgets/time/TimeView.java @@ -0,0 +1,20 @@ +package fr.pasteque.client.widgets.time; + +import fr.pasteque.client.utils.Date; +import fr.pasteque.client.widgets.TodayDate; + +/** + * Created by svirch_n on 29/04/16 + * Last edited at 11:28. + */ +public class TimeView extends DateTimeView { + + public TimeView(TodayDate todayDate, String preText, Date date) { + super(todayDate, preText, date); + } + + @Override + protected String getTimeFormat(Date date) { + return date.formatTime(); + } +} diff --git a/app/src/main/res/layout/invoice.xml b/app/src/main/res/layout/invoice.xml index a097e015..0b9b35bf 100644 --- a/app/src/main/res/layout/invoice.xml +++ b/app/src/main/res/layout/invoice.xml @@ -4,24 +4,57 @@ android:layout_height="match_parent" android:layout_width="match_parent"> - + - + - + + + + + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/layout/pdf_text_line.xml b/app/src/main/res/layout/pdf_text_line.xml index b946f06f..44edbe27 100644 --- a/app/src/main/res/layout/pdf_text_line.xml +++ b/app/src/main/res/layout/pdf_text_line.xml @@ -3,5 +3,5 @@ android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="SCIL" android:id="@+id/text_view" - android:textSize="@dimen/textSmall" + android:textSize="@dimen/textMedium" android:textColor="@android:color/black"/> \ No newline at end of file -- GitLab From e2dc3116c8c96249db2d44837d3121c1eb7913ca Mon Sep 17 00:00:00 2001 From: Nicolas Svirchevsky Date: Fri, 29 Apr 2016 12:46:21 +0200 Subject: [PATCH 7/9] Fixed discount --- .../java/fr/pasteque/client/PdfCreatorActivityTest.java | 2 +- .../main/java/fr/pasteque/client/widgets/pdf/PdfTicketRow.java | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/app/src/androidTest/java/fr/pasteque/client/PdfCreatorActivityTest.java b/app/src/androidTest/java/fr/pasteque/client/PdfCreatorActivityTest.java index 4d121989..10d3b670 100644 --- a/app/src/androidTest/java/fr/pasteque/client/PdfCreatorActivityTest.java +++ b/app/src/androidTest/java/fr/pasteque/client/PdfCreatorActivityTest.java @@ -25,7 +25,7 @@ public class PdfCreatorActivityTest extends ActivityInstrumentationTestCase2 receiptList = Data.Receipt.getReceipts(null); - Intent intent = new Intent().putExtra(PdfCreatorActivity.TICKET_TAG, receiptList.get(0).getTicket()); + Intent intent = new Intent().putExtra(PdfCreatorActivity.TICKET_TAG, receiptList.get(1).getTicket()); setActivityIntent(intent); } diff --git a/app/src/main/java/fr/pasteque/client/widgets/pdf/PdfTicketRow.java b/app/src/main/java/fr/pasteque/client/widgets/pdf/PdfTicketRow.java index 01dfb3ea..eab9a249 100644 --- a/app/src/main/java/fr/pasteque/client/widgets/pdf/PdfTicketRow.java +++ b/app/src/main/java/fr/pasteque/client/widgets/pdf/PdfTicketRow.java @@ -24,7 +24,7 @@ public class PdfTicketRow extends PdfRow { formatRound(ticketLine.getProductExcTax()), formatTax(ticketLine.getDiscountRate()), formatTax(ticketLine.getProduct().getTaxRate()), - formatRound(ticketLine.getTotalIncTax()) + formatRound(ticketLine.getTotalDiscPIncTax()) }; addElements(elements); } -- GitLab From e86c8367a9dd14981cbeee051f7ff87bd3b46cbe Mon Sep 17 00:00:00 2001 From: Nicolas Svirchevsky Date: Mon, 2 May 2016 16:29:28 +0200 Subject: [PATCH 8/9] Add/Edit/Create Customer to the invoice --- .../client/activities/PdfCreatorActivity.java | 85 +++++++++++++++++-- .../client/fragments/CustomerInfoDialog.java | 39 +++++++-- .../pasteque/client/widgets/CompanyView.java | 27 ++++-- .../main/res/menu/pdf_creator_activity.xml | 24 ++++++ app/src/main/res/values-fr/strings.xml | 1 + app/src/main/res/values/strings.xml | 1 + 6 files changed, 156 insertions(+), 21 deletions(-) create mode 100644 app/src/main/res/menu/pdf_creator_activity.xml diff --git a/app/src/main/java/fr/pasteque/client/activities/PdfCreatorActivity.java b/app/src/main/java/fr/pasteque/client/activities/PdfCreatorActivity.java index c111d937..d8ae8db7 100644 --- a/app/src/main/java/fr/pasteque/client/activities/PdfCreatorActivity.java +++ b/app/src/main/java/fr/pasteque/client/activities/PdfCreatorActivity.java @@ -1,9 +1,15 @@ package fr.pasteque.client.activities; import android.os.Bundle; +import android.view.Menu; +import android.view.MenuItem; +import android.view.View; import android.widget.TableLayout; import fr.pasteque.client.Pasteque; import fr.pasteque.client.R; +import fr.pasteque.client.fragments.CustomerInfoDialog; +import fr.pasteque.client.fragments.CustomerSelectDialog; +import fr.pasteque.client.models.Customer; import fr.pasteque.client.models.Ticket; import fr.pasteque.client.models.TicketLine; import fr.pasteque.client.widgets.CompanyView; @@ -12,7 +18,6 @@ import fr.pasteque.client.widgets.pdf.PdfTaxeRow; import fr.pasteque.client.widgets.pdf.PdfTicketRow; import fr.pasteque.client.widgets.pdf.PdfTotalRow; -import java.util.HashMap; import java.util.List; import java.util.Map; @@ -20,10 +25,60 @@ import java.util.Map; * Created by svirch_n on 25/04/16 * Last edited at 16:50. */ -public class PdfCreatorActivity extends TrackedActivity { +public class PdfCreatorActivity extends TrackedActivity implements CustomerSelectDialog.Listener, CustomerInfoDialog.CustomerListener { public static final String TICKET_TAG = "TICKET_TAG"; private static final int HEADER_PADDING = 10; + private static final int EDIT = 1; + private View.OnClickListener addCustomerListener = new View.OnClickListener() { + @Override + public void onClick(View v) { + addCustomer(); + } + }; + private Customer customer; + + private void addCustomer() { + CustomerSelectDialog dialog = CustomerSelectDialog.newInstance(true); + dialog.setDialogListener(PdfCreatorActivity.this); + dialog.show(getFragmentManager(), CustomerSelectDialog.TAG); + } + + @Override + public boolean onCreateOptionsMenu(Menu menu) { + getMenuInflater().inflate(R.menu.pdf_creator_activity, menu); + return super.onCreateOptionsMenu(menu); + } + + @Override + public boolean onOptionsItemSelected(MenuItem item) { + switch (item.getItemId()) { + case R.id.ab_menu_customer_add: + this.createCustomer(); + break; + case R.id.ab_menu_customer_list: + this.addCustomer(); + break; + case R.id.ab_menu_customer_edit: + this.editCustomer(); + break; + } + return true; + } + + private void createCustomer() { + CustomerInfoDialog customerInfoDialog = CustomerInfoDialog.newInstance(true, null); + customerInfoDialog.setDialogCustomerListener(this); + customerInfoDialog.show(getFragmentManager()); + } + + private void editCustomer() { + CustomerInfoDialog customerInfoDialog = CustomerInfoDialog.newInstance(true, this.customer); + customerInfoDialog.setDialogCustomerListener(this); + customerInfoDialog.show(getFragmentManager()); + } + + private CompanyView outerCompany; @Override public void onCreate(Bundle state) { @@ -40,10 +95,12 @@ public class PdfCreatorActivity extends TrackedActivity { private void fillInvoice(Ticket ticket) { setContentView(R.layout.pdf_invoice_viewer); ((CompanyView) findViewById(R.id.inner_company)).setCompany(Pasteque.getCompany()); + outerCompany = (CompanyView) findViewById(R.id.outer_company); if (ticket.getCustomer() != null) { - ((CompanyView) findViewById(R.id.outer_company)).setCompany(ticket.getCustomer().getCompany()); + outerCompany.setCompany(ticket.getCustomer().getCompany()); } else { - ((CompanyView) findViewById(R.id.outer_company)).noCompany(); + outerCompany.setListener(this.addCustomerListener); + outerCompany.noCompany(); } fillLines(ticket.getLines()); fillTaxes(ticket); @@ -71,7 +128,7 @@ public class PdfCreatorActivity extends TrackedActivity { addDivider(content); Map taxeValue = ticket.getTaxes(); Map excByTaxes = ticket.getExcByTaxes(); - for (Double taxe: taxeValue.keySet()) { + for (Double taxe : taxeValue.keySet()) { PdfTaxeRow row = new PdfTaxeRow(getApplicationContext(), content); row.setTaxe(taxe, taxeValue.get(taxe), excByTaxes.get(taxe)); } @@ -92,7 +149,7 @@ public class PdfCreatorActivity extends TrackedActivity { TableLayout content = (TableLayout) findViewById(R.id.ticket); addLinesHeader(content); addDivider(content); - for (TicketLine each: lines) { + for (TicketLine each : lines) { PdfTicketRow row = new PdfTicketRow(getApplicationContext(), content); row.setTicket(each); } @@ -106,4 +163,20 @@ public class PdfCreatorActivity extends TrackedActivity { public Pdf getPdf() { return (Pdf) findViewById(R.id.pdf); } + + @Override + public void onCustomerPicked(Customer customer) { + this.customer = customer; + if (customer != null) { + outerCompany.setCompany(customer.getCompany()); + } else { + outerCompany.setCompany(null); + } + } + + @Override + public void onCustomerCreated(Customer customer) { + this.customer = customer; + outerCompany.setCompany(customer.getCompany()); + } } diff --git a/app/src/main/java/fr/pasteque/client/fragments/CustomerInfoDialog.java b/app/src/main/java/fr/pasteque/client/fragments/CustomerInfoDialog.java index 47a3fc4e..604fbf90 100644 --- a/app/src/main/java/fr/pasteque/client/fragments/CustomerInfoDialog.java +++ b/app/src/main/java/fr/pasteque/client/fragments/CustomerInfoDialog.java @@ -268,11 +268,38 @@ public class CustomerInfoDialog extends DialogFragment @Override public void onClick(View v) { - //TODO: Handle customer edition if (!mbEditable) { getDialog().dismiss(); return; } + try { + Customer customer; + if (this.mCustomer != null) { + customer = editCustomer(); + } else { + customer = createCustomer(); + } + if (customer != null) { + send(customer); + } + } catch (NotConformException ignore){ + + } + } + + private Customer editCustomer() throws NotConformException { + throw new NotConformException(); + } + + private void send(Customer customer) { + if (Configure.getSyncMode(mCtx) == Configure.AUTO_SYNC_MODE) { + uploadCustomer(customer); + } else { + storeLocalCustomer(customer); + } + } + + private Customer createCustomer() throws NotConformException { String firstNameStr = mName.getText().toString(); String lastNameStr = mName.getText().toString(); String address1Str = ""; @@ -300,12 +327,9 @@ public class CustomerInfoDialog extends DialogFragment address2Str, zipCodeStr, cityStr, departmentStr, countryStr, mailStr, phone1Str, phone2Str, faxStr, 0.0, 0.0, 0.0, "0", noteStr); - if (Configure.getSyncMode(mCtx) == Configure.AUTO_SYNC_MODE) { - uploadCustomer(c); - } else { - storeLocalCustomer(c); - } + return c; } + throw new NotConformException(); } private boolean isEmailValid(CharSequence email) { @@ -499,4 +523,7 @@ public class CustomerInfoDialog extends DialogFragment b.show(); } } + + private class NotConformException extends Throwable { + } } diff --git a/app/src/main/java/fr/pasteque/client/widgets/CompanyView.java b/app/src/main/java/fr/pasteque/client/widgets/CompanyView.java index d0ae2e4b..5d1cf14f 100644 --- a/app/src/main/java/fr/pasteque/client/widgets/CompanyView.java +++ b/app/src/main/java/fr/pasteque/client/widgets/CompanyView.java @@ -4,6 +4,7 @@ import android.annotation.TargetApi; import android.content.Context; import android.os.Build; import android.util.AttributeSet; +import android.view.View; import android.view.ViewGroup; import android.widget.ImageView; import android.widget.RelativeLayout; @@ -19,7 +20,7 @@ import java.util.Map; * Last edited at 12:06. */ public class CompanyView extends RelativeLayout { - + private static final String DEFAULT_TEXT = "N/A"; private static final int PADDING = 0; private static int name = 1; @@ -54,7 +55,7 @@ public class CompanyView extends RelativeLayout { setPadding(PADDING, PADDING, PADDING, PADDING); int[] ids = {CompanyView.name, CompanyView.address, CompanyView.city, CompanyView.country}; int above = 0; - for (int each: ids) { + for (int each : ids) { TextView textView = (TextView) inflate(getContext(), R.layout.pdf_text_line, null); textView.setId(each); textView.setText(CompanyView.DEFAULT_TEXT); @@ -76,11 +77,15 @@ public class CompanyView extends RelativeLayout { } public void setCompany(Company company) { - showText(); - setText(name, company.name); - setText(address, company.address.address); - setText(city, company.address.city + " " + company.address.postCode); - setText(country, company.address.country); + if (company != null) { + showText(); + setText(name, company.name); + setText(address, company.address.address); + setText(city, company.address.city + " " + company.address.postCode); + setText(country, company.address.country); + } else { + showLogo(); + } } private void setText(int id, String text) { @@ -92,7 +97,7 @@ public class CompanyView extends RelativeLayout { } private void showLogo() { - for (TextView each: views.values()) { + for (TextView each : views.values()) { each.setVisibility(INVISIBLE); } logo.setVisibility(VISIBLE); @@ -100,9 +105,13 @@ public class CompanyView extends RelativeLayout { } private void showText() { - for (TextView each: views.values()) { + for (TextView each : views.values()) { each.setVisibility(VISIBLE); } logo.setVisibility(INVISIBLE); } + + public void setListener(View.OnClickListener listener) { + this.setOnClickListener(listener); + } } diff --git a/app/src/main/res/menu/pdf_creator_activity.xml b/app/src/main/res/menu/pdf_creator_activity.xml new file mode 100644 index 00000000..0b929d84 --- /dev/null +++ b/app/src/main/res/menu/pdf_creator_activity.xml @@ -0,0 +1,24 @@ + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/values-fr/strings.xml b/app/src/main/res/values-fr/strings.xml index 4ccf4cec..9f97f587 100644 --- a/app/src/main/res/values-fr/strings.xml +++ b/app/src/main/res/values-fr/strings.xml @@ -330,5 +330,6 @@ Rapport par mail Envoie des rapports d\'erreur par mail Facture + Modifier un client diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 4c867f9f..a4c4906c 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -344,5 +344,6 @@ Mail reporting Enable mail reporting Invoice + Edit customer -- GitLab From 3d17569a7a8ea9dd8d67171417c7af0b3e8e8a8d Mon Sep 17 00:00:00 2001 From: Nicolas Svirchevsky Date: Mon, 2 May 2016 18:01:30 +0200 Subject: [PATCH 9/9] Invoice can be sent by mail --- .../client/activities/PdfCreatorActivity.java | 87 +++++++++++++++++++ .../client/utils/file/ExternalFile.java | 4 +- .../fr/pasteque/client/utils/file/File.java | 4 +- .../client/utils/file/InternalFile.java | 8 +- .../main/res/menu/pdf_creator_activity.xml | 5 ++ app/src/main/res/values-fr/err_string.xml | 3 + app/src/main/res/values-fr/strings.xml | 3 + app/src/main/res/values/err_string.xml | 3 + app/src/main/res/values/strings.xml | 3 + 9 files changed, 114 insertions(+), 6 deletions(-) diff --git a/app/src/main/java/fr/pasteque/client/activities/PdfCreatorActivity.java b/app/src/main/java/fr/pasteque/client/activities/PdfCreatorActivity.java index d8ae8db7..d266d74d 100644 --- a/app/src/main/java/fr/pasteque/client/activities/PdfCreatorActivity.java +++ b/app/src/main/java/fr/pasteque/client/activities/PdfCreatorActivity.java @@ -1,5 +1,8 @@ package fr.pasteque.client.activities; +import android.content.Context; +import android.content.Intent; +import android.net.Uri; import android.os.Bundle; import android.view.Menu; import android.view.MenuItem; @@ -12,14 +15,20 @@ import fr.pasteque.client.fragments.CustomerSelectDialog; import fr.pasteque.client.models.Customer; import fr.pasteque.client.models.Ticket; import fr.pasteque.client.models.TicketLine; +import fr.pasteque.client.utils.CouldNotCreatePdfException; +import fr.pasteque.client.utils.file.ExternalFile; +import fr.pasteque.client.utils.file.File; +import fr.pasteque.client.utils.file.InternalFile; import fr.pasteque.client.widgets.CompanyView; import fr.pasteque.client.widgets.pdf.Pdf; import fr.pasteque.client.widgets.pdf.PdfTaxeRow; import fr.pasteque.client.widgets.pdf.PdfTicketRow; import fr.pasteque.client.widgets.pdf.PdfTotalRow; +import java.io.*; import java.util.List; import java.util.Map; +import java.util.UUID; /** * Created by svirch_n on 25/04/16 @@ -30,6 +39,7 @@ public class PdfCreatorActivity extends TrackedActivity implements CustomerSelec public static final String TICKET_TAG = "TICKET_TAG"; private static final int HEADER_PADDING = 10; private static final int EDIT = 1; + private static final java.lang.String PDF_DIRECTORY = "invoice"; private View.OnClickListener addCustomerListener = new View.OnClickListener() { @Override public void onClick(View v) { @@ -50,6 +60,12 @@ public class PdfCreatorActivity extends TrackedActivity implements CustomerSelec return super.onCreateOptionsMenu(menu); } + @Override + public boolean onPrepareOptionsMenu(Menu menu) { + menu.findItem(R.id.ab_menu_send).setEnabled(this.customer != null); + return super.onPrepareOptionsMenu(menu); + } + @Override public boolean onOptionsItemSelected(MenuItem item) { switch (item.getItemId()) { @@ -62,10 +78,80 @@ public class PdfCreatorActivity extends TrackedActivity implements CustomerSelec case R.id.ab_menu_customer_edit: this.editCustomer(); break; + case R.id.ab_menu_send: + this.sendInvoice(); + break; } return true; } + private void sendInvoice() { + InternalFile file = createPdf(); + if (file != null) { + sendMail(file); + } + finish(); + } + + private void sendMail(File file) { + File copy = copyInTempCache(file); + Intent intent = new Intent(Intent.ACTION_SEND); + intent.setType("message/rfc822"); + intent.putExtra(Intent.EXTRA_EMAIL, this.customer.getMail()); + intent.putExtra(Intent.EXTRA_SUBJECT, "Invoice " + copy.getName()); + intent.putExtra(Intent.EXTRA_TEXT, "Thank you!"); + intent.putExtra(Intent.EXTRA_STREAM, Uri.parse("file://" + copy.getAbsolutePath())); + try { + startActivity(Intent.createChooser(intent, getString(R.string.pick_email_client))); + } catch (android.content.ActivityNotFoundException ex) { + Pasteque.Toast.show(R.string.err_no_email_client); + } + } + + private File copyInTempCache(File file) { + File result = new ExternalFile(getApplicationContext().getCacheDir().getPath(), file.getName()); + InputStream in = null; + OutputStream out = null; + try { + in = file.openRead(); + out = result.openWrite(); + byte[] buf = new byte[1024]; + int len; + while ((len = in.read(buf)) > 0) { + out.write(buf, 0, len); + } + } catch (IOException e) { + e.printStackTrace(); + } finally { + try { + if (in != null) { + in.close(); + } + if (out != null) { + out.close(); + } + } catch (IOException e) { + e.printStackTrace(); + } + } + return result; + } + + private InternalFile createPdf() { + String filename = "invoice_" + UUID.randomUUID() + ".pdf"; + InternalFile internalFile = null; + try { + internalFile = new InternalFile(PDF_DIRECTORY, filename, Context.MODE_WORLD_READABLE); + FileOutputStream fileOutputStream = internalFile.openWrite(); + getPdf().build(fileOutputStream); + + } catch (FileNotFoundException | CouldNotCreatePdfException e) { + e.printStackTrace(); + Pasteque.Toast.show(R.string.err_create_pdf); + } + return internalFile; + } + private void createCustomer() { CustomerInfoDialog customerInfoDialog = CustomerInfoDialog.newInstance(true, null); customerInfoDialog.setDialogCustomerListener(this); @@ -87,6 +173,7 @@ public class PdfCreatorActivity extends TrackedActivity implements CustomerSelec if (bundle != null) { Ticket ticket = (Ticket) bundle.getSerializable(PdfCreatorActivity.TICKET_TAG); if (ticket != null) { + this.customer = ticket.getCustomer(); fillInvoice(ticket); } } diff --git a/app/src/main/java/fr/pasteque/client/utils/file/ExternalFile.java b/app/src/main/java/fr/pasteque/client/utils/file/ExternalFile.java index f4f4c472..189fbb61 100644 --- a/app/src/main/java/fr/pasteque/client/utils/file/ExternalFile.java +++ b/app/src/main/java/fr/pasteque/client/utils/file/ExternalFile.java @@ -33,12 +33,12 @@ public class ExternalFile extends File { * @throws FileNotFoundException */ @Override - protected FileInputStream openRead() throws FileNotFoundException { + public FileInputStream openRead() throws FileNotFoundException { return null; } @Override - protected FileOutputStream openWrite() throws FileNotFoundException { + public FileOutputStream openWrite() throws FileNotFoundException { return new FileOutputStream(this); } } \ No newline at end of file diff --git a/app/src/main/java/fr/pasteque/client/utils/file/File.java b/app/src/main/java/fr/pasteque/client/utils/file/File.java index 0748da1e..d90b0ead 100644 --- a/app/src/main/java/fr/pasteque/client/utils/file/File.java +++ b/app/src/main/java/fr/pasteque/client/utils/file/File.java @@ -84,7 +84,7 @@ public abstract class File extends java.io.File { return result; } - protected abstract FileInputStream openRead() throws FileNotFoundException; + public abstract FileInputStream openRead() throws FileNotFoundException; - protected abstract FileOutputStream openWrite() throws FileNotFoundException; + public abstract FileOutputStream openWrite() throws FileNotFoundException; } diff --git a/app/src/main/java/fr/pasteque/client/utils/file/InternalFile.java b/app/src/main/java/fr/pasteque/client/utils/file/InternalFile.java index 053f6c28..b95bc414 100644 --- a/app/src/main/java/fr/pasteque/client/utils/file/InternalFile.java +++ b/app/src/main/java/fr/pasteque/client/utils/file/InternalFile.java @@ -21,15 +21,19 @@ public class InternalFile extends File { super(Pasteque.getAppContext().getDir(path, Context.MODE_PRIVATE), fileName); } + public InternalFile(String path, String fileName, int mode) { + super(Pasteque.getAppContext().getDir(path, mode), fileName); + } + public InternalFile(String dir, int directory) { super(dir, directory); } - protected FileInputStream openRead() throws FileNotFoundException { + public FileInputStream openRead() throws FileNotFoundException { return new FileInputStream(this); } - protected FileOutputStream openWrite() throws FileNotFoundException { + public FileOutputStream openWrite() throws FileNotFoundException { return new FileOutputStream(this); } } diff --git a/app/src/main/res/menu/pdf_creator_activity.xml b/app/src/main/res/menu/pdf_creator_activity.xml index 0b929d84..b8addcb4 100644 --- a/app/src/main/res/menu/pdf_creator_activity.xml +++ b/app/src/main/res/menu/pdf_creator_activity.xml @@ -20,5 +20,10 @@ android:showAsAction="ifRoom|withText" android:title="@string/menu_edit_customer" /> + \ No newline at end of file diff --git a/app/src/main/res/values-fr/err_string.xml b/app/src/main/res/values-fr/err_string.xml index 9e5966ee..0791e2c0 100644 --- a/app/src/main/res/values-fr/err_string.xml +++ b/app/src/main/res/values-fr/err_string.xml @@ -47,4 +47,7 @@ Les données doivent être envoyées avant de se déconnecter La caisse est ouverte et doit être fermée Barcode erroné + + Impossible de créer le PDF + diff --git a/app/src/main/res/values-fr/strings.xml b/app/src/main/res/values-fr/strings.xml index 9f97f587..8f3372cd 100644 --- a/app/src/main/res/values-fr/strings.xml +++ b/app/src/main/res/values-fr/strings.xml @@ -331,5 +331,8 @@ Envoie des rapports d\'erreur par mail Facture Modifier un client + Envoyer + Il n\'y a pas de client mail d\'installé. + Choisir un client mail diff --git a/app/src/main/res/values/err_string.xml b/app/src/main/res/values/err_string.xml index 026c453a..f60c3359 100644 --- a/app/src/main/res/values/err_string.xml +++ b/app/src/main/res/values/err_string.xml @@ -47,4 +47,7 @@ Local data must be sent to disconnect Cash is opened and must be closed Wrong barcode + + Could not create pdf +9 diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index a4c4906c..86ad7e85 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -345,5 +345,8 @@ Enable mail reporting Invoice Edit customer + Send + There are no email clients installed. + Pick an Email client -- GitLab