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


/*!
    @class       BITimeSlip
    @abstract    BITimeSlip is a representation of a working slip and handles any behaviour regarding a working slip.
    @discussion  Working slips represent work which is being done for a client.  A slip can be of several kinds, Timed, Flat, Expense, Mileage and Quantity.
 
                 The difference between the kinds are...
 
                 Timed - the silp will be timed using the timer or with manual time entries, and the calculation of the total will be based on the duration of the slip.
 
                 Flat - the slip can still be timed using the timer or manually with time entries, but the calculation of the total will be based solely on the amount which was specified on the slip and will not vary on duration at all.
 
                 Quantity - the total is based on quantity * amount.  This applies in the case of widgets.  I will sell you 10 widgets at $10 a piece.
  
                 Expense - the total is based on the amount alone.  I had to buy paper for work I was doing for you.  That paper cost $50.
 
                 Mileage - the total is based on amount per km or mi * the number of km or mi.  I drove 50 km to get to your office and I charge $0.45 a km.
 
 
                 ISSUES
 
                 - we should move out the subtotal, markup, discount, total logic to another entity so we are not always repeating this logic.
 
                 - we should move out the tax calculation to another entity, tax manager should be good for this.
 
                 - we should remove all stale info, ie. old tax stuff.. tax1, tax2.
*/


#ifdef BILLINGS_PRO
#import "_BPTimeSlip.h"
#endif
#ifdef BILLINGS_SINGLE
#import "_BITimeSlip.h"
#endif
#import "BIAppVersioning.h"


@class BITax;
@class BISlipTemplate;
@class BIProject;
@class BIDatabaseObjectContext;
@class BIClient;
@class BICurrency;

@interface BITimeSlip : BL_SUPER_CLASSNAME_MUNGE(TimeSlip) 
{
	BOOL timerExists;
	BITimeEntry* _activeTimeEntry;
	long _cachedDuration;
	NSNumber *slipTemplateID; // used in BP for ordering on the server side
    NSDate* _timerStartDateReference; // used to calculate elapsed time of running timer
}

+ (NSString*)timeDisplayWithNumSeconds:(long)totalSec;

@property (retain) NSNumber *slipTemplateID;

- (void)setDefaultValues;

- (BITimeSlip*)selfForTimer;
- (void)setSelfForTimer: (BITimeSlip*)aSlip;

- (BITimeEntry *)activeTimeEntry;
- (void)setActiveTimeEntry:(BITimeEntry *)anActiveTimeEntry;

- (BOOL)timerExists;
- (void)setTimerExists:(BOOL)anAnswer;

- (long)cachedDuration;
- (void)setCachedDuration:(long)aCachedDuration;

- (id)quantityDuration;
- (void)setQuantityDuration:(id)aValue;

- (id)quantityDurationNilSafe;

// these methods are used just to trigger an update to everything
// which is bound to quantityDuration
// these methods don't do anything
// ie. Time Entries call this, so that when a new time entry is added
// they can prompt a quantityDuration update, so that everyone bound to
// quantity duration is updated, as quantity duration just derives its value
// from summing up the time entries
- (id)updateQuantityDuration;

// in seconds
- (long)totalDurationOfTimeEntries;
- (long)totalDurationOfTimeEntriesIncludingRounding;


- (long)durationInHours;

- (long)calculateDurationInSecondsRoundedToMinute;

// in seconds
- (long)durationInSeconds;
- (void)invalidateTimeSlipDurationCached;

- (BOOL)isDueDate;
- (void)setIsDueDate:(BOOL)flag;

- (BOOL)isCompleteDate;
- (void)setIsCompleteDate:(BOOL)flag;

- (BOOL)isStartDate;
- (void)setIsStartDate:(BOOL)flag;

- (BOOL)isInvoiced;

- (BOOL)isUnlinked;

- (BOOL)isReadyToBeBilled;
- (BOOL)isTimedOrFlatCompleted;

- (NSString*)invoicedDateString;

- (BOOL)activeForTimingBool;
- (void)setActiveForTimingBool:(BOOL)aFlag;

- (NSString*)kindName;

- (NSString*)natureName;

#pragma mark Derived Value Methods

- (NSNumber*)derivedDiscountTotal;

- (NSNumber*)derivedCombinedTaxTotal;

- (NSNumber*)tax1Total;

- (NSNumber*)tax2Total;

- (BOOL)useTax1Bool;
- (void)setUseTax1Bool:(BOOL)flag;

- (BOOL)useTax2Bool;
- (void)setUseTax2Bool:(BOOL)flag;

- (BOOL)compoundSecondaryTaxBool;
- (void)setCompoundSecondaryTaxBool:(BOOL)flag;

- (long)numHoursFromDurationInSeconds:(long)aDuration;
- (long)numMinutesFromDurationInSeconds:(long)aDuration;

- (NSString *)formattedDerivedSubTotal;
- (NSNumber*)derivedSubTotal;

- (NSNumber *)baseDerivedTotal;
- (NSString *)formattedDerivedTotal;
- (NSNumber*)derivedTotal;
- (void)invalidateTimeSlipTotalCached;

- (NSNumber*)derivedMarkupTotal;

- (NSNumber*)derivedSubTotalForInvoice;
- (void)setDerivedSubTotalForInvoice:(NSNumber*)aTotal;

#pragma mark Timer stuff
/* Timer stuff begin */
- (BOOL)startTimer;
- (BOOL)stopTimer;
- (void)update:(id)aTimerManager;
- (void)startStopTimer;

/* Timer sutff end */

- (NSString*)mileageDisplayName;

- (NSString*)mileagePerDisplayName;

- (NSString*)quantityDurationString;
- (NSString*)quantityDurationRoundedString;

- (NSString*)quantityDecimalDurationString;
- (NSString*)quantityDecimalDurationRoundedString;


- (NSString *)measurementUnit;

- (BOOL)isTimedOrFlat;

- (id)copyWithZone:(NSZone *)zone;

- (void)applyTemplate:(BISlipTemplate*)aTemplate;

- (NSArray*)contributeExportFields;
- (NSArray*)dictionariesForExpandTaxTotals;
- (NSString*)tabDelimitedRepresentation:(NSArray*)fieldDicts;

- (NSString *)formattedTaxesTotal;
- (NSNumber*)taxesTotal;

- (NSNumber*)taxTotalForTax:(BITax*)matchTax;

- (NSString*)applicableTaxNames;

- (void)relinkToProject:(BIProject*)aProject;

- (BITimeSlip*)duplicateWithoutEstimateSlipRelationship:(BOOL)appendCopy;

- (void)refreshCachedDuration;

/*!
 Compares the cached the value to calculated duration value and resets if needed.
 */
- (void)recalculateCachedValuesIfNeeded;


- (NSString *)formattedRate;

- (NSCalendarDate*)smartDate;
- (void)setSmartDate:(NSCalendarDate*)aDate;

- (NSNumber*)ratePlusMarkup;
- (NSNumber*)ratePlusMarkupMinusDiscount;

- (NSDecimalNumber*)discountAsPercent;
- (NSDecimalNumber*)markupAsPercent;

- (NSNumber*)subtotalPlusMarkupMinusDiscount;

- (NSString*)ratePlusMarkupMinusDiscountString;

- (void)setInitialValues;
- (void)setInitialValuesWithObjectContext:(id)oc;

- (void)setupNewImportedSlip;

- (BITimeEntry*)mostRecentTimeEntry;

- (NSString *)archivableRepresentationName;

- (NSArray*)plistKeys;
- (NSDictionary*)plistRepresentation;
- (void)restoreValuesFromPlist:(NSDictionary*)aDict;

- (NSNumber*)totalUsedToCalculateTax:(BITax*)theTax;

- (NSString*)categoryName;
- (void)setCategoryName:(NSString*)aName;

- (NSString*)workerName;

- (NSString*)typeString;

- (BIClient *)client;

- (NSDictionary*)bexRepresentationFromEstimateSlipBEXRepresentation:(NSDictionary*)estBex;

- (NSString*)prettyEntityName;

- (BOOL)combineWithSlip:(BITimeSlip*)aSlip;

- (void)bumpToRoundTime;

- (void)applyRatesFromClient;

- (BOOL)rateMatchesDefaultsUsingObjectContext:(BIDatabaseObjectContext*)aContext;

- (BITimeSlip *)slipForMyEyesOnly;
- (BITimeSlip *)slipForDoneCell;

- (NSNumberFormatter *)currencyFormatter;
- (BICurrency *)currency;

- (void)setUpdateQuantityDuration:(id)aValue;

#ifdef BILLINGS_PRO

- (BOOL)isWaitingForApproval;
- (BOOL)isApproved;
- (void)markAsApprovedByUser:(BIUser *)aUser;

- (BOOL)canApprove;
- (void)markAsApproved;

- (BOOL)canReject;
- (void)markAsRejected;
#endif

@end
