
// BIClient.h
// BISubstrate
// 
// Copyright (c) 2001 Marketcircle Inc. All rights reserved.


#ifdef BILLINGS_PRO
#import "_BPClient.h"
#endif
#ifdef BILLINGS_SINGLE
#import "_BIClient.h"
#endif
#import "BIAppVersioning.h"


@class ABPerson;
@class BICurrencyConversionAgent;


/*!
    @class       BIClient
    @abstract    BIClient represents a client who we are performing work for.
    @discussion  A client is the root object for all the work pertaining to the client.  Therefore, all the clients projects hang off of the client.
 
                 Each client has a corresponding ABPerson which is stored in the Address Book under the Billings group.
*/


@interface BIClient : BL_SUPER_CLASSNAME_MUNGE(Client) 
{
}

/*!
    @method     derivedName
    @abstract   returns the appropriate name based on whether or not its a company or person
    @discussion if its a person, return first last name.. if its a company return company name
    @result     returns the derived name
*/

- (NSString *)name;
- (NSString*)derivedName;
- (NSString*)derivedCompany;
- (NSString *)derivedLastNameFirst;
- (NSString*)derivedFullName;

- (NSString *)archivableRepresentationName;

- (NSString *)namePrimary;
- (NSString *)nameSecondary;

// includes prefix, suffix, middlename
- (NSString *)formalFullName;

- (NSString*)escapedName;

- (void)setImageData:(NSData *)imgData;

- (NSString*)clientCategoryName;

- (NSNumber *)total;

- (NSNumber*)retainersBalance;
- (void)invalidateClientRetainersBalance;

- (NSNumber *)balance;
- (void)invalidateClientBalance;

/*!
 Returns an array of BIPayments that are of method 'retainer'
 */
- (NSArray *)retainerPayments;

/*!
 Returns an array of BIPayments that are method 'retainer' and BIRetainer.
 */
- (NSMutableArray *)retainersAndRetainerPayments;


- (NSNumber *)appliedRetainerAmt;
- (void)updateAppliedRetainerAmt;

- (BOOL)isOverdue;
- (NSNumber *)overdueAmount;
- (void)invalidateClientOverdueAmount;

- (NSNumber *)unbilledAmount;
- (NSNumber *)baseUnbilledAmount;
- (void)invalidateClientUnbilledAmount;

- (NSNumber *)incompleteAmount;
- (NSNumber *)baseIncompleteAmount;
- (void)invalidateClientIncompleteAmount;

- (void)invalidateClientAmounts;

- (void)recalculateCachedValuesIfNeeded;

- (NSCalendarDate *)firstOutstandingDate;

- (NSArray *)activeTimeslips;
- (NSArray *)readyToBeBilledTimeSlips;

- (NSArray *)estimates;

#pragma mark Address Book

/**
 Uses the -clientABLinks to try and find a record in the local address book.
 
 @warning The related address book framework lookup can be expensive.
 @see +abPersonFromABRef:
 */
- (ABPerson *)abPerson;

/**
 Searches the Mac's AddressBook for a person with a matching UUID.
 
 Use if you want to fetch the -clientABRef separately from searching in the Address Book.
 
 @param abRef Get using -clientABRef
 */
+ (ABPerson *)abPersonFromABRef:(NSString *)abRef;

/**
 @warning Requires a full lookup in the address book, so can be expensive.
 */
- (BOOL)hasABPerson;

- (NSString *)clientABRef;

- (BIClientABLink *)clientABLinkForCurrentDevice;
- (BOOL)hasClientABLink;
- (BOOL)hasUnapprovedABChanges;
- (NSNumber *)unapprovedABChanges;

- (void)linkToABPerson:(ABPerson *)anABPerson;
- (BOOL)searchForAndlinkToMatchingABPersonIfNecessary;

/**
 Looks up the client's abPerson and updates prefix, middle name, suffix, nick name, job title, department, main email, mailing address, and photo.
 
 @see -updateClientFromABPerson:
 */
- (void)updateClientFromABPerson;

/**
 Like -updateClientFromABPerson, but uses 'person' instead of looking it up.
 
 @param person the address book object to use for updating. Should be retrieved through -abPerson.
 
 @see -updateClientFromABPerson
 */
- (void)updateClientFromABPerson:(ABPerson*)person;
- (BOOL)createABPersonFromClient;

/*!
 Takes the values from the ABPerson object. Does not link to the ABRecord. This meant more for dragging vcards into the app
 */
- (void)takeValuesFromABPerson:(ABPerson *)anABPerson;

// AB - Name

- (BOOL)cachedNameDiffersFromAB;
- (NSString *)namePrimaryValueFromAB;
- (NSString *)nameSecondaryValueFromAB;
- (NSString *)fullNameValueFromAB;
- (void)acceptNameValueFromAB;

// AB - Photo

- (void)updatePhotoFromABIfChanged;

// AB - Email

- (BOOL)hasCachedEmail;
- (BOOL)cachedEmailMissingFromAB;
- (BOOL)cachedEmailDiffersFromAB;
- (NSString *)emailValueFromAB;
- (void)acceptEmailValueFromAB;

- (NSArray *)emailDictionaries;
- (NSArray *)emailDictionariesFromAB;
- (NSArray *)emailDictionaries:(BOOL)ensureCachedEntryExists;
- (NSDictionary *)emailDictionary;
- (void)setEmailDictionary:(NSDictionary *)emailDict;

// AB - Address

- (BOOL)hasCachedAddress;
- (BOOL)cachedAddressMissingFromAB;
- (BOOL)cachedAddressDiffersFromAB;
- (NSDictionary *)addressValueFromAB;
- (NSString *)addressFormattedValueFromAB;
- (NSString *)addressFormattedValueFromABAsOneLine;
- (void)acceptAddressValueFromAB;

- (NSString *)addressFormattedAsOneLine;

- (NSArray *)addressDictionaries;
- (NSArray *)addressDictionariesFromAB;
- (NSArray *)addressDictionaries:(BOOL)ensureCachedEntryExists;
- (NSDictionary *)addressDictionary;
- (void)setAddressDictionary:(NSDictionary *)addressDict;
- (NSAttributedString *)formattedAddressUsingAB;
- (void)storeFormattedAddress;

// AB - Phone

- (NSArray *)phoneDictionaries;
@property (nonatomic, retain) NSString *primaryPhone;

// MultiCurrency

/*!
 If the locale is not explicitely set, tries to derive it from the country. Returns nil if it cannot determine the locale.
 */
- (NSLocale *)locale;
- (void)setLocale:(NSLocale *)aLocale;

- (BOOL)isUsingForeignCurrency;
- (BOOL)isUsingBaseCurrency;
- (NSNumberFormatter *)currencyFormatter;
- (NSString *)currencySymbol;
- (NSString *)currencyCode;
- (NSNumber *)baseCurrencyValueForForeignValue:(NSNumber *)aNumber;

- (NSNumber *)baseBalance;
- (NSNumber *)baseIncompleteAmount;
- (NSNumber *)baseOverdueAmount;
- (NSNumber *)baseRetainersBalance;
- (NSNumber *)baseUnbilledAmount;

/*!
 Convenience for the report engine
 */
- (BICurrencyConversionAgent *)baseCurrencyConversion;
- (BICurrencyConversionAgent *)baseCurrencyConversionWithTildeFormat;

/*!
 DEPRECATED!
 */
- (NSString *)accountingSystemID;
- (void)setAccountingSystemID:(NSString *)anStrID;

/*!
 Returns YES if any of this client's invoice has applied taxes
 */
- (BOOL)paidSomeTaxes;

@end
