All Downloads are FREE. Search and download functionalities are using the official Maven repository.

net.dreceiptx.receipt.DigitalReceiptGenerator Maven / Gradle / Ivy

There is a newer version: 1.16.4
Show newest version
/*
 * Copyright 2016 Digital Receipt Exchange Limited
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package net.dreceiptx.receipt;

import net.dreceiptx.config.ConfigManager;
import net.dreceiptx.receipt.allowanceCharge.ReceiptAllowanceCharge;
import net.dreceiptx.client.ExchangeClient;
import net.dreceiptx.receipt.document.ReceiptContact;
import net.dreceiptx.receipt.document.ReceiptContactType;
import net.dreceiptx.receipt.document.StandardBusinessDocumentHeader;
import net.dreceiptx.receipt.invoice.Invoice;
import net.dreceiptx.receipt.lineitem.LineItem;
import net.dreceiptx.receipt.lineitem.StandardLineItem;
import net.dreceiptx.receipt.serialization.json.DigitalReceiptSerializer;
import net.dreceiptx.receipt.serialization.json.InvoiceSerializer;
import net.dreceiptx.receipt.serialization.json.LineItemSerializer;
import net.dreceiptx.receipt.serialization.json.PaymentReceiptsSerializer;
import net.dreceiptx.receipt.settlement.PaymentMethodType;
import net.dreceiptx.receipt.settlement.PaymentReceipt;
import net.dreceiptx.receipt.tax.Tax;
import net.dreceiptx.receipt.tax.TaxCategory;
import net.dreceiptx.receipt.tax.TaxCode;
import net.dreceiptx.users.UserIdentifierType;
import net.dreceiptx.client.exception.ExchangeClientException;
import net.dreceiptx.receipt.validation.ReceiptValidation;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.google.gson.annotations.SerializedName;
import com.google.gson.reflect.TypeToken;
import net.dreceiptx.receipt.common.*;

import java.math.BigDecimal;
import java.util.*;
import java.util.concurrent.atomic.AtomicInteger;

public class DigitalReceiptGenerator {
    @SerializedName("standardBusinessDocumentHeader")
    private StandardBusinessDocumentHeader _standardBusinessDocumentHeader;
    @SerializedName("invoice")
    private Invoice _invoice;
    @SerializedName("paymentReceipts")
    private List _paymentReceipts;

    private final static AtomicInteger _paymentReceiptId = new AtomicInteger(1);
    private final ConfigManager _configManager;
    private ExchangeClient _exchangeClient;
    private String _dRxGLN;
    private String _merchantGLN;
    private String _userGUID;
    private TaxCategory _defaultTaxCategory;
    private TaxCode _defaultTaxCode;
    private net.dreceiptx.receipt.common.Currency _defaultCurrency;
    private String _defaultLanguage;
    private String _defaultTimeZone;
    private String _defaultCountry;

    public DigitalReceiptGenerator(ConfigManager configManager) throws ExchangeClientException {
        _configManager = configManager;
        _defaultCountry = validateConfigOption("default.country");
        _defaultLanguage =  validateConfigOption("default.language");
        _defaultTimeZone = validateConfigOption("default.timezone");
        _defaultCurrency = net.dreceiptx.receipt.common.Currency.codeOf(validateConfigOption("default.currency"));
        _defaultTaxCategory = Enum.valueOf(TaxCategory.class, validateConfigOption("default.taxCategory"));
        _defaultTaxCode = Enum.valueOf(TaxCode.class, validateConfigOption("default.taxCode"));

        _standardBusinessDocumentHeader = new StandardBusinessDocumentHeader();
        _standardBusinessDocumentHeader.setdRxGLN(validateConfigOption("drx.gln"));
        _standardBusinessDocumentHeader.setMerchantGLN(validateConfigOption("merchant.gln"));
        _standardBusinessDocumentHeader.getDocumentIdentification().setTypeVersion(validateConfigOption("receipt.version"));
        _standardBusinessDocumentHeader.getDocumentIdentification().setCreationDateAndTime(Calendar.getInstance().getTime());

        _paymentReceipts = new ArrayList<>();
        _invoice = new Invoice(_configManager);
    }
    
    public void setMerchantGLN(String merchantGLN) {
        _standardBusinessDocumentHeader.setMerchantGLN(merchantGLN);
    }
    
    public void setUserGUID(UserIdentifierType userIdentifierType, String userIdentifierValue) throws ExchangeClientException {
        _userGUID = userIdentifierType.getValue()+":"+userIdentifierValue;
        _standardBusinessDocumentHeader.setUserIdentifier(_userGUID);
    }
    
    public void setMerchantReference(String merchantReference){
        _standardBusinessDocumentHeader.getDocumentIdentification().setInstanceIdentifier(merchantReference);
        
        if(_invoice.getInvoiceIdentification() == null){
            _invoice.setInvoiceIdentification(merchantReference);
        }
    }

    //TODO: Setters without getters?
    public void setReceiptCurrency(net.dreceiptx.receipt.common.Currency currency) {
        _defaultCurrency = currency;
    }

    public void setReceiptLanguage(String languageCode) {
        _defaultLanguage = languageCode;
    }
    
    public void setReceiptDateTime(Date invoiceDate) {
        _invoice.setCreationDateTime(invoiceDate);
    }
    
    public void setPurchaseOrderNumber(String purchaseOrder) {
        _invoice.setPurchaseOrder(purchaseOrder);
    }

    public void setCustomerReferenceNumber(String customerReference) {
        _invoice.setCustomerReference(customerReference);
    }

    public void setBillingInformation(String name) {
        _invoice.setBillingInformation(name);
    }

    public void setSalesOrderReference(String salesOrderReference) {
        _invoice.setSalesOrderReference(salesOrderReference);
    }
    
    public void addClientRecipientContact(String name, String email, String phone){
        addRMSContact(ReceiptContactType.RECIPIENT_CONTACT, name, email, phone);
    }
    
    public void addClientRecipientContact(String name, String email){
        addRMSContact(ReceiptContactType.RECIPIENT_CONTACT, name, email, null);
    }
    
    public void addClientRecipientContact(String name){
        addRMSContact(ReceiptContactType.RECIPIENT_CONTACT, name, null, null);
    }
    
    public void addClientPurchasingContact(String name, String email, String phone){
        addRMSContact(ReceiptContactType.PURCHASING_CONTACT, name, email, phone);
    }
    
    public void addClientPurchasingContact(String name, String email){
        addRMSContact(ReceiptContactType.PURCHASING_CONTACT, name, email, null);
    }
    
    public void addClientPurchasingContact(String name){
        addRMSContact(ReceiptContactType.PURCHASING_CONTACT, name, null, null);
    }
    
    private void addRMSContact(ReceiptContactType type, String name, String email, String phone){
        ReceiptContact rmsContact = new ReceiptContact(type, name);
        if(email != null){rmsContact.addEmailAddress(email);}
        if(phone != null){rmsContact.addTelephoneNumber(phone);}
        _standardBusinessDocumentHeader.addRMSContact(rmsContact);
    }
    
    public void addMerchantCustomerRelationsContact(String name, String email, String phone){
        addMerchantContact(ReceiptContactType.CUSTOMER_RELATIONS, name, email, phone);
    }
    
    public void addMerchantCustomerRelationsContact(String name, String email){
        addMerchantContact(ReceiptContactType.CUSTOMER_RELATIONS, name, email, null);
    }
    
    public void addMerchantCustomerRelationsContact(String name){
        addMerchantContact(ReceiptContactType.CUSTOMER_RELATIONS, name, null, null);
    }
    
    public void addMerchantDeliveryContact(String name, String email, String phone){
        addMerchantContact(ReceiptContactType.DELIVERY_CONTACT, name, email, phone);
    }
    
    public void addMerchantDeliveryContact(String name, String email){
        addMerchantContact(ReceiptContactType.DELIVERY_CONTACT, name, email, null);
    }
    
    public void addMerchantDeliveryContact(String name){
        addMerchantContact(ReceiptContactType.DELIVERY_CONTACT, name, null, null);
    }
    
    public void addMerchantSalesAssistantContact(String name, String email, String phone){
        addMerchantContact(ReceiptContactType.SALES_ADMINISTRATION, name, email, phone);
    }
    
    public void addMerchantSalesAssistantContact(String name, String email){
        addMerchantContact(ReceiptContactType.SALES_ADMINISTRATION, name, email, null);
    }
    
    public void addMerchantSalesAssistantContact(String name){
        addMerchantContact(ReceiptContactType.SALES_ADMINISTRATION, name, null, null);
    }
    
    private void addMerchantContact(ReceiptContactType type, String name, String email, String phone){
        ReceiptContact merchantContact = new ReceiptContact(type, name);
        if(email != null){merchantContact.addEmailAddress(email);}
        if(phone != null){merchantContact.addTelephoneNumber(phone);}
        _standardBusinessDocumentHeader.addMerchantContact(merchantContact);
    }
    
    public void setReceiptNumber(String receiptNumber){
        _invoice.setInvoiceIdentification(receiptNumber);
        
        if(_standardBusinessDocumentHeader.getDocumentIdentification().getInstanceIdentifier() == null){
            _standardBusinessDocumentHeader.getDocumentIdentification().setInstanceIdentifier(receiptNumber);
        }
    }

    public int addLineItem(LineItem lineItem) {
        for (Tax lineItemTax : lineItem.getTaxes()) {
            configureTax(lineItemTax);
        }
        return _invoice.addLineItem(lineItem);
    }
    
    //TODO: Why are these Integers? does a null quantity make sense?
    //TODO: Integer to int and Double to double
    public int addLineItem(String brand, String name, int quantity, double price) {
        LineItem lineItem = new StandardLineItem(brand, name, "", quantity, price);
        return _invoice.addLineItem(lineItem);
    }
    
    public int addLineItem(String brand, String name, int quantity, double price, Tax tax) {
        LineItem lineItem = new StandardLineItem(brand, name, "", quantity, price);
        lineItem.addTax(configureTax(tax));
        return _invoice.addLineItem(lineItem);
    }

    public int addLineItem(String brand, String name, String description, int quantity, double price) {
        LineItem lineItem = new StandardLineItem(brand, name, description, quantity, price);
        return _invoice.addLineItem(lineItem);
    }

    public int addLineItem(String brand, String name, String description, int quantity, double price, Tax tax) {
        LineItem lineItem = new StandardLineItem(brand, name, description, quantity, price);
        lineItem.addTax(configureTax(tax)); 
        return _invoice.addLineItem(lineItem);
    }

    public int addLineItem(String brand, String name, String description, int quantity, double price, double taxRate, boolean taxInclusive) {
        LineItem lineItem;

        if (taxInclusive) {
            BigDecimal netPrice = BigDecimal.valueOf(price).multiply((BigDecimal.valueOf(1).subtract(BigDecimal.valueOf(taxRate))));
            BigDecimal total = BigDecimal.valueOf(quantity).multiply(netPrice);
            Tax tax = new Tax(_defaultTaxCategory, _defaultTaxCode, total.doubleValue(), taxRate);
            lineItem = new StandardLineItem(brand, name, description, quantity, price);
            lineItem.addTax(tax);
        } else {
            BigDecimal netPrice = BigDecimal.valueOf(price);
            BigDecimal total = BigDecimal.valueOf(quantity).multiply(netPrice);
            Tax tax = new Tax(_defaultTaxCategory, _defaultTaxCode, total.doubleValue(), taxRate);
            lineItem = new StandardLineItem(brand, name, description, quantity, price);
            lineItem.addTax(tax);
        }

        return _invoice.addLineItem(lineItem);
    }

    public int addPaymentReceipt(PaymentMethodType paymentMethodCode, Double paymentAmount) {
        PaymentReceipt paymentReceipt = new PaymentReceipt(paymentMethodCode, paymentAmount);
        paymentReceipt.setSettlementCurrency(_defaultCurrency);
        paymentReceipt.setId(_paymentReceiptId.getAndIncrement());
        _paymentReceipts.add(paymentReceipt);
        return paymentReceipt.getId();
    }

    public int addPaymentReceipt(PaymentReceipt paymentReceipt) {
        paymentReceipt.setId(_paymentReceiptId.getAndIncrement());
        paymentReceipt.setSettlementCurrency(_defaultCurrency);
        _paymentReceipts.add(paymentReceipt);
        return paymentReceipt.getId();
    }

    public void removePaymentReceipt(int paymentId) {
        PaymentReceipt item = null;
        for (PaymentReceipt paymentReceipt : _paymentReceipts) {
            if (paymentReceipt.getId() == paymentId) {
                item = paymentReceipt;
                break;
            }
        }
        if (item != null) {
            _paymentReceipts.remove(item);
        }
    }

    public void addGeneralDiscount(double amount, String description) {
        _invoice.addAllowanceOrCharge(ReceiptAllowanceCharge.GeneralDiscount(amount, description));
    }
    
    public void addGeneralDiscount(double amount, String description, Tax tax) {
        _invoice.addAllowanceOrCharge(ReceiptAllowanceCharge.GeneralDiscount(amount, description, configureTax(tax)));
    }

    public void addTip(double amount, String description) {
        _invoice.addAllowanceOrCharge(ReceiptAllowanceCharge.Tip(amount, description));
    }
    
    public void addTip(double amount, String description, Tax tax) {
        _invoice.addAllowanceOrCharge(ReceiptAllowanceCharge.Tip(amount, description, configureTax(tax)));
    }

    public void addPackagingFee(double amount, String description) {
        _invoice.addAllowanceOrCharge(ReceiptAllowanceCharge.PackagingFee(amount, description));
    }
    
    public void addPackagingFee(double amount, String description, Tax tax) {
        _invoice.addAllowanceOrCharge(ReceiptAllowanceCharge.PackagingFee(amount, description, configureTax(tax)));
    }

    public void addDeliveryFee(double amount, String description) {
        _invoice.addAllowanceOrCharge(ReceiptAllowanceCharge.DeliveryFee(amount, description));
    }
    
    public void addDeliveryFee(double amount, String description, Tax tax) {
        _invoice.addAllowanceOrCharge(ReceiptAllowanceCharge.DeliveryFee(amount, description, configureTax(tax)));
    }

    public void addFrieghtFee(double amount, String description) {
        _invoice.addAllowanceOrCharge(ReceiptAllowanceCharge.FreightFee(amount, description));
    }
    
    public void addFrieghtFee(double amount, String description, Tax tax) {
        _invoice.addAllowanceOrCharge(ReceiptAllowanceCharge.FreightFee(amount, description, configureTax(tax)));
    }

    public void addProcessingFee(double amount, String description) {
        _invoice.addAllowanceOrCharge(ReceiptAllowanceCharge.ProcessingFee(amount, description));
    }
    
    public void addProcessingFee(double amount, String description, Tax tax) {
        _invoice.addAllowanceOrCharge(ReceiptAllowanceCharge.ProcessingFee(amount, description, configureTax(tax)));
    }
    
    public void addBookingFee(double amount, String description) {
        _invoice.addAllowanceOrCharge(ReceiptAllowanceCharge.BookingFee(amount, description));
    }
    
    public void addBookingFee(double amount, String description, Tax tax) {
        _invoice.addAllowanceOrCharge(ReceiptAllowanceCharge.BookingFee(amount, description, configureTax(tax)));
    }

    public void addAdminFee(double amount, String description) {
        _invoice.addAllowanceOrCharge(ReceiptAllowanceCharge.AdminFee(amount, description));
    }

    public void addAdminFee(double amount, String description, Tax tax) {
        _invoice.addAllowanceOrCharge(ReceiptAllowanceCharge.AdminFee(amount, description, this.configureTax(tax)));
    }

    public void addAmendmentFee(double amount, String description) {
        _invoice.addAllowanceOrCharge(ReceiptAllowanceCharge.AmendmentFee(amount, description));
    }

    public void addAmendmentFee(double amount, String description, Tax tax) {
        _invoice.addAllowanceOrCharge(ReceiptAllowanceCharge.AmendmentFee(amount, description, this.configureTax(tax)));
    }

    public void addServiceFee(double amount, String description) {
        _invoice.addAllowanceOrCharge(ReceiptAllowanceCharge.ServiceFee(amount, description));
    }

    public void addServiceFee(double amount, String description, Tax tax) {
        _invoice.addAllowanceOrCharge(ReceiptAllowanceCharge.ServiceFee(amount, description, this.configureTax(tax)));
    }

    public void addReturnOrCancellationFee(double amount, String description) {
        _invoice.addAllowanceOrCharge(ReceiptAllowanceCharge.ReturnOrCancellationFee(amount, description));
    }

    public void addReturnOrCancellationFee(double amount, String description, Tax tax) {
        _invoice.addAllowanceOrCharge(ReceiptAllowanceCharge.ReturnOrCancellationFee(amount, description, this.configureTax(tax)));
    }

    public void setDeliveryInformation(DeliveryInformation deliveryInformation) {
        _invoice.setDestinationInformation(deliveryInformation.getLocationInformation());
        _invoice.getAllowanceOrCharges().addAll(deliveryInformation.getDeliveryFees());
        _invoice.setDespatchInformation(deliveryInformation.getDespatchInformation());
    }

    public void setDeliveryAddress(Address address) {
        _invoice.getDestinationInformation().setAddress(address);
    }

    public void setDeliveryAddress(Address address, Contact contact) {
        _invoice.getDestinationInformation().setAddress(address);
        _invoice.getDestinationInformation().addContact(contact);
    }

    public void setDestinationCoordinates(GeographicalCoordinates geographicalCoordinates) {
        _invoice.getDestinationInformation().setGeographicalCoordinates(geographicalCoordinates);
    }

    public void setDeliveryDate(Date deliverDate) {
        _invoice.getDespatchInformation().setDeliveryDate(deliverDate);
    }

    public void setOriginAddress(Address address) {
        _invoice.getOriginInformation().setAddress(address);
    }

    public void setOriginAddress(Address address, Contact contact) {
        _invoice.getOriginInformation().setAddress(address);
        _invoice.getOriginInformation().addContact(contact);
    }

    public void setOriginCoordinates(GeographicalCoordinates geographicalCoordinates) {
        _invoice.getOriginInformation().setGeographicalCoordinates(geographicalCoordinates);
    }

    public void validate() {
        ReceiptValidation receiptValidation = new ReceiptValidation();
        _standardBusinessDocumentHeader.validate(receiptValidation);
        _invoice.validate(receiptValidation);
    }
    
    private Tax configureTax(Tax tax){
        if(tax.getTaxCategory() == null){
            tax.setTaxCategory(_defaultTaxCategory);
        }
        
        if(tax.getTaxCode()== null){
            tax.setTaxCode(_defaultTaxCode);
        }
        return tax;
    }

    public String encodeJson() {
        DigitalReceiptSerializer digitalReceiptMapper = new DigitalReceiptSerializer();
        digitalReceiptMapper.setInvoice(_invoice);
        digitalReceiptMapper.setStandardBusinessDocumentHeader(_standardBusinessDocumentHeader);
        digitalReceiptMapper.setPaymentReceipts(_paymentReceipts);
        Gson gson = new GsonBuilder()
                .setDateFormat("yyyy-MM-dd'T'HH:mm:ssZ")
                .registerTypeAdapter(Invoice.class, new InvoiceSerializer(_defaultCurrency))
                .registerTypeHierarchyAdapter(LineItem.class, new LineItemSerializer(_defaultCurrency))
                .registerTypeAdapter(new TypeToken>() {
                }.getType(), new PaymentReceiptsSerializer(_dRxGLN, _merchantGLN, _userGUID))
                .create();
        String digitalReceiptJson = gson.toJson(digitalReceiptMapper);
        return digitalReceiptJson;
    }
    
    private String validateConfigOption(String configParameter) throws ExchangeClientException {
        if(_configManager.exists(configParameter)){
            return _configManager.getConfigValue(configParameter);
        }else{
            throw new ExchangeClientException(101, "Required config parameter "+configParameter+" not supplied");
        }
    }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy