//
//  Invoice.h
//  iOrdning
//
//  Created by Erik Aderstedt on 2008-04-28.
//  Copyright 2008 Aderstedt Software AB. All rights reserved.
//

#if defined(IFAKTURA)
#import <Foundation/Foundation.h>
#import <CoreData/CoreData.h>
#else
#import <Cocoa/Cocoa.h>
#endif

enum InvoiceStatus {
	AS_IS_NOTSENT='Nose',
	AS_IS_SENT='Sent',
	AS_IS_OVERDUE='Over',
	AS_IS_PAID='Paid',
	AS_IS_REMINDER='Rem1',
	AS_IS_REMINDER2='Rem2',
	AS_IS_LOSS='Loss',
	AS_IS_PARTIALLY_PAID='PPai',
	AS_IS_RETURNED='Retu'
};


enum ASInvoiceLineColumn {
    kASInvoiceLineNumber =          0x0001,
    kASInvoiceLineArticleNumber =   0x0002,
    kASInvoiceLineArticleName =     0x0004,
    kASInvoiceLineDiscount =        0x0008,
    kASInvoiceLineComment =         0x0010,
    kASInvoiceLinePcs =             0x0020,
    kASInvoiceLineUnit =            0x0040,
    kASInvoiceLinePrice =           0x0080,
    kASInvoiceLinePriceInclVat =    0x0100,
    kASInvoiceLineVatLevel =        0x0200,
    kASInvoiceLineVatAmount =       0x0400,
    kASInvoiceLineAmount =          0x0800,
    kASInvoiceLineAmountInclVat =   0x1000
};

enum ASInvoiceStatus {
    kASInvoiceStatusUnknown,
    kASInvoiceStatusSent,
    kASInvoiceStatusOverdue,
    kASInvoiceStatusPaid,
    kASInvoiceStatusReminder,
    kASInvoiceStatusReminder2,
    kASInvoiceStatusLoss,
    kASInvoiceStatusPartiallyPaid,
    kASInvoiceStatusReturned
};

@class Company;
@class Entry;
@class Allowance;
@class Tag;
@class Account;
@class Article;
@class Language;
@class Template;
@class BusinessContact;

//
// Sending an invoice:
//
// -(BOOL)sendWithExchangeRate:(NSNumber *)eRate error:(NSError **)error
//
// Attempts to send an invoice with the given exchange rate.
//

@interface Invoice : NSManagedObject

@property(nonatomic, retain) NSString *attention;
@property(nonatomic, retain) NSNumber *bookOnce;
@property(nonatomic, retain) NSString *city;
@property(nonatomic, retain) NSString *company;
@property(nonatomic, retain) NSString *county;
@property(nonatomic, retain) NSString *country;
@property(nonatomic, retain) NSString *creditDetails;
@property(nonatomic, retain) NSString *currency;
@property(nonatomic, retain) NSNumber *custLossDate;
@property(nonatomic, retain) NSNumber *date;
@property(nonatomic, retain) NSNumber *days;
@property(nonatomic, retain) NSString *deliveryMethod;
@property(nonatomic, retain) NSNumber *dueDate;
@property(nonatomic, retain) NSDecimalNumber *exchangeRate;
@property(nonatomic, retain) NSString *language;
@property(nonatomic, retain) NSString *note;
@property(nonatomic, retain) NSString *number;
@property(nonatomic, retain) NSString *ourRef;
@property(nonatomic, retain) NSDecimalNumber *localAmount;
@property(nonatomic, retain) NSDecimalNumber *localAmountExclVat;
@property(nonatomic, retain) NSDecimalNumber *paidAmount;
@property(nonatomic, retain) NSNumber *paidDate;
@property(nonatomic, retain) NSString *purchaseOrderNo;
@property(nonatomic, retain) NSNumber *rounding;
@property(nonatomic, retain) NSNumber *status;
@property(nonatomic, retain) NSString *street;
@property(nonatomic, retain) NSNumber *vatfree;
@property(nonatomic, retain) NSString *vatno;
@property(nonatomic, retain) NSString *yourRef;
@property(nonatomic, retain) NSString *zipcode;
@property(nonatomic, retain) NSOrderedSet *lines;
@property(nonatomic, retain) Tag *tag;
@property(nonatomic, retain) NSString *templateName;
@property(nonatomic, retain) NSNumber *fieldMask;
@property(nonatomic, retain) NSNumber *showDeliveryAddress;
@property(nonatomic, retain) NSNumber *deliveryDate;
@property(nonatomic, retain) NSNumber *showDeliveryDate;
@property(nonatomic, retain) NSNumber *enableIRPF;
@property(nonatomic, retain) NSDecimalNumber *irpfRate;
@property(nonatomic, retain) NSDecimalNumber *discount;

@property(nonatomic, retain) NSString *d_street;
@property(nonatomic, retain) NSString *d_attention;
@property(nonatomic, retain) NSString *d_zipcode;
@property(nonatomic, retain) NSString *d_city;
@property(nonatomic, retain) NSString *d_county;
@property(nonatomic, retain) NSString *d_country;

@property(nonatomic, retain) Company *sender;
@property(nonatomic, retain) BusinessContact *customer;

@property(nonatomic, strong) NSDecimalNumber *cache;

+ (Invoice *)latestNumberedInvoiceInContext:(NSManagedObjectContext *)context;
- (void)setPropertiesFromLatestInvoice;

// Dependent keys.
- (NSNumber *)sendable;
- (NSString *)recipient;
- (NSInteger)numericInvoiceNumber;
- (NSString *)nextNumber;

#if !defined(IFAKTURA)
@property(nonatomic,retain) Template *invoiceTemplate;
#endif

- (BOOL)shouldShowInvoiceLineColumn:(enum ASInvoiceLineColumn)column;
- (void)clearShownInvoiceLineColumns;
- (void)setShouldShowInvoiceLineColumn:(enum ASInvoiceLineColumn)column;

- (NSDecimalNumber *)netAmount;
- (NSDecimalNumber *)discountAmount;
- (NSString *)allowanceString;
- (NSDecimalNumber *)vatAmount;
- (NSDecimalNumber *)irpfAmount;
- (NSDecimalNumber *)roundingAmount;
- (NSDecimalNumber *)totalAmount;

- (NSDecimalNumber *)amountRemaining;
- (NSDictionary *)amountsForEachVatLevel;
- (NSString *)vatSummary;
- (NSString *)vatSummaryUsingFormatter:(NSNumberFormatter *)formatter;
- (NSNumber *)isEmpty;
- (NSNumber *)isPaid;
- (NSNumber *)isOverdue;
- (NSNumber *)canBePaid;
- (NSNumber *)isSent ;
- (NSNumber *)isLossOrReturn;
- (NSString *)creditDetails;
- (NSNumber *)days;
- (NSAttributedString *)indicator;
- (NSNumber *)status;
- (NSNumber *)rawStatus;
- (void)setRawStatus:(NSNumber *)s;
- (NSArray *)sortedInvoiceLines;
- (NSNumber *)foreignCurrency;
- (NSString *)deliveryAddress;
- (NSNumber *)isExport;

- (NSString *)title;
- (NSString *)reminder;
- (NSString *)registeredForTax;
- (NSString *)registeredForVAT;
- (NSString *)address;
- (NSString *)senderAddress;
- (void)copyValuesFromCustomer;

// State actions
- (BOOL)remindWithArticle:(Article *)reminderArticle amount:(NSDecimalNumber *)amount error:(NSError **)outError;
- (BOOL)sendWithKontantMetoden:(NSNumber *)bOnce error:(NSError **)error;
- (BOOL)send:(NSError **)error;
- (BOOL)payMeWithFinalAmount:(NSDecimalNumber *)finalAmount onDateIndex:(NSNumber *)paymentDay inFull:(BOOL)full receivingAccount:(Account *)receivingAccount error:(NSError **)error;
- (BOOL)payMeWithFinalAmount:(NSDecimalNumber *)finalAmount onDateIndex:(NSNumber *)paymentDay inFull:(BOOL)full receivingAccount:(Account *)receivingAccount entry:(Entry **)entry error:(NSError **)error;
- (BOOL)registerReturnWithError:(NSError **)error usingAccount:(Account *)a;
- (BOOL)registerCustomerLossWithError:(NSError **)error usingAccount:(Account *)a;

// Helper functions
- (Entry *)insertReversedSalesEntry:(NSError **)error withAccountForAlreadyPaid:(Account *)a;

+ (NSString *)sendEntryNameForNumber:(NSObject *)number;
- (NSString *)sendEntryName;
+ (NSString *)paidEntryNameForNumber:(NSObject *)number;
- (NSString *)paidEntryName;
+ (NSString *)partiallyPaidEntryNameForNumber:(NSObject *)number;
- (NSString *)partiallyPaidName;

- (BOOL)addSaleRowsToEntry:(Entry *)entry withExchangeRate:(NSDecimalNumber *)eRate;
- (void)removeEmptyLines;

- (Invoice *)duplicate;

+ (NSMutableAttributedString *)attributedStringIndicatorForInvoiceStatus:(NSNumber *)status;

- (NSNumber *)canRevertToNotSent;
- (void)revertToNotSent;

@end
