Really, this should be it, for the passing income.
[capital-apms-progress.git] / process / gencshfl.p
blob421c7cefef5fead57bb79a0f10336b389caac5f1
1 &ANALYZE-SUSPEND _VERSION-NUMBER UIB_v8r12
2 &ANALYZE-RESUME
3 &ANALYZE-SUSPEND _UIB-CODE-BLOCK _CUSTOM _DEFINITIONS Procedure
4 /*--------------------------------------------------------------------------------------------
5 File : process/gencshfl.p
6 Purpose : Generate forecast cash flow records
7 Author(s) : Tyrone McAuley & Andrew McMillan
8 ------------------------------------------------------------------------*/
10 DEF INPUT PARAMETER process-options AS CHAR NO-UNDO.
11 DEF VAR scenario-code LIKE Scenario.ScenarioCode NO-UNDO.
12 DEF VAR do-service AS LOGI NO-UNDO INITIAL No.
13 DEF VAR do-rentals AS LOGI NO-UNDO INITIAL No.
14 DEF VAR debug-mode AS LOGI NO-UNDO INITIAL No.
15 RUN parse-options.
17 {inc/ofc-this.i}
18 {inc/ofc-acct.i "RENT" "control-rent-account"}
19 {inc/ofc-set.i "RentCharge-Type" "rent-charge-type" "WARNING"}
20 {inc/ofc-set-l.i "Property-MarketPerUnit" "market-per-unit"}
21 IF NOT AVAILABLE(OfficeSetting) THEN market-per-unit = No.
22 {inc/ofc-set-l.i "Property-ParksPerMonth" "parks-per-month"}
23 IF NOT AVAILABLE(OfficeSetting) THEN parks-per-month = No.
24 {inc/ofc-set.i "Area-Units" "area-units"}
25 IF NOT AVAILABLE(OfficeSetting) THEN area-units = "Sq.M".
27 ON WRITE OF CashFlow DO:
28 IF NEW CashFlow THEN DO:
29 DEF BUFFER LastCashFlow FOR CashFlow.
30 FIND LAST LastCashFlow WHERE
31 LastCashFlow.ScenarioCode = CashFlow.ScenarioCode AND
32 LastCashFlow.EntityType = CashFlow.EntityType AND
33 LastCashFlow.EntityCode = CashFlow.EntityCode AND
34 LastCashFlow.AccountCode = CashFlow.AccountCode AND
35 LastCashFlow.CashFlowType = CashFlow.CashFlowType
36 NO-LOCK NO-ERROR.
37 ASSIGN CashFlow.Sequence = IF AVAILABLE LastCashFlow THEN
38 LastCashFlow.Sequence + 1 ELSE 1.
39 END.
40 END.
42 /* Selection variables */
44 DEF VAR entity-list AS CHAR NO-UNDO.
45 DEF VAR entity-list-type AS CHAR NO-UNDO.
46 DEF VAR entity-list-by AS CHAR NO-UNDO.
47 DEF VAR all-entities AS LOGI NO-UNDO.
49 DEF VAR exclude-areas AS CHAR NO-UNDO.
50 DEF VAR exclude-contracts AS CHAR NO-UNDO.
51 DEF VAR forecast-start AS DATE NO-UNDO.
52 DEF VAR forecast-end AS DATE NO-UNDO.
53 DEF VAR market-date AS DATE NO-UNDO.
55 DEF VAR base-growth AS DECIMAL NO-UNDO.
57 /* Vraibales for rental cash flows */
58 DEF VAR include-vacant-space AS LOGI NO-UNDO.
59 DEF VAR include-releasing AS LOGI NO-UNDO.
60 DEF VAR include-reviews AS LOGI NO-UNDO.
61 DEF VAR apply-ratchets AS LOGI NO-UNDO.
62 DEF VAR def-re-lease-length AS INT NO-UNDO.
63 DEF VAR def-re-lease-delay AS INT NO-UNDO.
64 DEF VAR review-months AS INT NO-UNDO.
65 DEF VAR monthly-length AS INT NO-UNDO.
67 DEF VAR def-contract-account AS DEC NO-UNDO.
68 DEF VAR def-rent-account AS DEC NO-UNDO.
70 DEF WORK-TABLE /* TEMP-TABLE */ delta-i NO-UNDO
71 FIELD type AS CHAR
72 FIELD subtype AS CHAR
73 FIELD pc AS DEC
74 /* INDEX x1 IS UNIQUE PRIMARY type subtype */.
76 /* _UIB-CODE-BLOCK-END */
77 &ANALYZE-RESUME
80 &ANALYZE-SUSPEND _UIB-PREPROCESSOR-BLOCK
82 /* ******************** Preprocessor Definitions ******************** */
84 &Scoped-define PROCEDURE-TYPE Procedure
88 /* _UIB-PREPROCESSOR-BLOCK-END */
89 &ANALYZE-RESUME
92 /* ************************ Function Prototypes ********************** */
94 &ANALYZE-SUSPEND _UIB-CODE-BLOCK _FUNCTION-FORWARD check-manual-flow Procedure
95 FUNCTION check-manual-flow RETURNS LOGICAL
96 ( INPUT man-type AS CHAR, INPUT chg-type AS CHAR, INPUT id-cd AS CHAR, INPUT-OUTPUT d-1 AS DATE, INPUT-OUTPUT d-n AS DATE ) FORWARD.
98 /* _UIB-CODE-BLOCK-END */
99 &ANALYZE-RESUME
101 &ANALYZE-SUSPEND _UIB-CODE-BLOCK _FUNCTION-FORWARD get-growth Procedure
102 FUNCTION get-growth RETURNS DECIMAL
103 ( INPUT base-date AS DATE, INPUT change-date AS DATE, INPUT modifiers AS CHAR ) FORWARD.
105 /* _UIB-CODE-BLOCK-END */
106 &ANALYZE-RESUME
108 &ANALYZE-SUSPEND _UIB-CODE-BLOCK _FUNCTION-FORWARD get-logical-parameter Procedure
109 FUNCTION get-logical-parameter RETURNS LOGICAL
110 ( INPUT parameter-id AS CHAR ) FORWARD.
112 /* _UIB-CODE-BLOCK-END */
113 &ANALYZE-RESUME
115 &ANALYZE-SUSPEND _UIB-CODE-BLOCK _FUNCTION-FORWARD get-new-rental Procedure
116 FUNCTION get-new-rental RETURNS DECIMAL
117 ( INPUT d-rent AS DATE, INPUT mkt-rent AS DEC, INPUT d-mkt AS DATE, INPUT modifiers AS CHAR, OUTPUT descr AS CHAR ) FORWARD.
119 /* _UIB-CODE-BLOCK-END */
120 &ANALYZE-RESUME
122 &ANALYZE-SUSPEND _UIB-CODE-BLOCK _FUNCTION-FORWARD get-parameter Procedure
123 FUNCTION get-parameter RETURNS CHARACTER
124 ( INPUT parameter-name AS CHAR ) FORWARD.
126 /* _UIB-CODE-BLOCK-END */
127 &ANALYZE-RESUME
129 &ANALYZE-SUSPEND _UIB-CODE-BLOCK _FUNCTION-FORWARD id-code Procedure
130 FUNCTION id-code RETURNS CHARACTER
131 ( INPUT type AS CHAR ) FORWARD.
133 /* _UIB-CODE-BLOCK-END */
134 &ANALYZE-RESUME
136 &ANALYZE-SUSPEND _UIB-CODE-BLOCK _FUNCTION-FORWARD include-contract Procedure
137 FUNCTION include-contract RETURNS LOGICAL
138 ( /* parameter-definitions */ ) FORWARD.
140 /* _UIB-CODE-BLOCK-END */
141 &ANALYZE-RESUME
143 &ANALYZE-SUSPEND _UIB-CODE-BLOCK _FUNCTION-FORWARD include-property Procedure
144 FUNCTION include-property RETURNS LOGICAL
145 ( /* parameter-definitions */ ) FORWARD.
147 /* _UIB-CODE-BLOCK-END */
148 &ANALYZE-RESUME
150 &ANALYZE-SUSPEND _UIB-CODE-BLOCK _FUNCTION-FORWARD renew-contract Procedure
151 FUNCTION renew-contract RETURNS DATE
152 ( INPUT start-date AS DATE, INPUT relation AS CHAR, INPUT ac AS DEC, INPUT amt AS DEC, INPUT description AS CHAR ) FORWARD.
154 /* _UIB-CODE-BLOCK-END */
155 &ANALYZE-RESUME
157 &ANALYZE-SUSPEND _UIB-CODE-BLOCK _FUNCTION-FORWARD reviews-from Procedure
158 FUNCTION reviews-from RETURNS CHARACTER
159 ( INPUT d-1 AS DATE, INPUT d-n AS DATE, INPUT months AS INT ) FORWARD.
161 /* _UIB-CODE-BLOCK-END */
162 &ANALYZE-RESUME
164 &ANALYZE-SUSPEND _UIB-CODE-BLOCK _FUNCTION-FORWARD to-number Procedure
165 FUNCTION to-number RETURNS DECIMAL
166 ( INPUT txtnum AS CHAR ) FORWARD.
168 /* _UIB-CODE-BLOCK-END */
169 &ANALYZE-RESUME
172 /* *********************** Procedure Settings ************************ */
174 &ANALYZE-SUSPEND _PROCEDURE-SETTINGS
175 /* Settings for THIS-PROCEDURE
176 Type: Procedure
177 Allow:
178 Frames: 0
179 Add Fields to: Neither
180 Other Settings: CODE-ONLY COMPILE
182 &ANALYZE-RESUME _END-PROCEDURE-SETTINGS
184 /* ************************* Create Window ************************** */
186 &ANALYZE-SUSPEND _CREATE-WINDOW
187 /* DESIGN Window definition (used by the UIB)
188 CREATE WINDOW Procedure ASSIGN
189 HEIGHT = .35
190 WIDTH = 40.
191 /* END WINDOW DEFINITION */
193 &ANALYZE-RESUME
197 &ANALYZE-SUSPEND _UIB-CODE-BLOCK _CUSTOM _INCLUDED-LIB Procedure
198 /* ************************* Included-Libraries *********************** */
200 {inc/method/m-debug.i}
201 {inc/date.i}
203 /* _UIB-CODE-BLOCK-END */
204 &ANALYZE-RESUME
208 &ANALYZE-SUSPEND _UIB-CODE-BLOCK _CUSTOM _MAIN-BLOCK Procedure
211 /* *************************** Main Block *************************** */
212 &SCOP KEEP-DEBUG-MESSAGES KEEP-MESSAGES
213 {&DEBUG-BEGIN}
215 FIND Scenario WHERE Scenario.ScenarioCode = scenario-code NO-LOCK.
217 debug-event("Starting").
218 RUN get-parameters.
219 IF RETURN-VALUE = "FAIL" THEN RETURN.
220 RUN delete-current-cash-flows.
221 IF do-service THEN RUN service-contracts.
222 IF do-rentals THEN RUN rental.
224 MESSAGE "Forecast Regeneration Complete" VIEW-AS ALERT-BOX INFORMATION
225 TITLE "Completed".
227 debug-event("Finished").
228 {&DEBUG-END}
230 /* _UIB-CODE-BLOCK-END */
231 &ANALYZE-RESUME
234 /* ********************** Internal Procedures *********************** */
236 &ANALYZE-SUSPEND _UIB-CODE-BLOCK _PROCEDURE create-flow Procedure
237 PROCEDURE create-flow :
238 /*------------------------------------------------------------------------------
239 Purpose:
240 ------------------------------------------------------------------------------*/
241 DEF INPUT PARAMETER cf-type AS CHAR NO-UNDO.
242 DEF INPUT PARAMETER chg-type AS CHAR NO-UNDO.
243 DEF INPUT PARAMETER account AS DEC NO-UNDO.
244 DEF INPUT PARAMETER start-date AS DATE NO-UNDO.
245 DEF INPUT PARAMETER end-date AS DATE NO-UNDO.
246 DEF INPUT PARAMETER frequency-code AS CHAR NO-UNDO.
247 DEF INPUT PARAMETER amount AS DEC NO-UNDO.
248 DEF INPUT PARAMETER description AS CHAR NO-UNDO.
249 DEF INPUT PARAMETER related-key AS CHAR NO-UNDO.
251 DEF VAR manual-flow-type AS CHAR NO-UNDO.
253 IF start-date > forecast-end THEN RETURN.
254 IF start-date > end-date THEN RETURN.
256 IF cf-type = "RENT" THEN manual-flow-type = "MRNT".
257 ELSE IF cf-type = "SCL" THEN manual-flow-type = "MSCL".
258 ELSE manual-flow-type = "".
260 IF manual-flow-type <> "" THEN DO:
261 IF NOT check-manual-flow( manual-flow-type, chg-type, related-key,
262 INPUT-OUTPUT start-date, INPUT-OUTPUT end-date ) THEN RETURN.
263 END.
265 CREATE CashFlow.
266 ASSIGN CashFlow.ScenarioCode = Scenario.ScenarioCode
267 CashFlow.EntityType = "P"
268 CashFlow.EntityCode = Property.PropertyCode
269 CashFlow.RelatedKey = related-key
270 CashFlow.CashFlowType = cf-type
271 CashFlow.CFChangeType = chg-type
272 CashFlow.AccountCode = account
273 CashFlow.StartDate = start-date
274 CashFlow.EndDate = (IF end-date >= forecast-end THEN ? ELSE end-date)
275 CashFlow.FrequencyCode = frequency-code
276 CashFlow.Amount = amount
277 CashFlow.Description = description.
279 END PROCEDURE.
281 /* _UIB-CODE-BLOCK-END */
282 &ANALYZE-RESUME
285 &ANALYZE-SUSPEND _UIB-CODE-BLOCK _PROCEDURE delete-current-cash-flows Procedure
286 PROCEDURE delete-current-cash-flows :
287 /*------------------------------------------------------------------------------
288 Purpose:
289 ------------------------------------------------------------------------------*/
290 IF do-rentals THEN DO:
291 debug-event("Deleting current RENT cash flows").
292 FOR EACH CashFlow OF Scenario WHERE CashFlow.ScenarioCode = scenario-code
293 AND CashFlow.CashFlowType = "RENT":
294 DELETE CashFlow.
295 END.
296 END.
298 IF do-service THEN DO:
299 debug-event("Deleting current SCL cash flows").
300 FOR EACH CashFlow OF Scenario WHERE CashFlow.ScenarioCode = scenario-code
301 AND CashFlow.CashFlowType = "SCL":
302 DELETE CashFlow.
303 END.
304 END.
305 END PROCEDURE.
307 /* _UIB-CODE-BLOCK-END */
308 &ANALYZE-RESUME
311 &ANALYZE-SUSPEND _UIB-CODE-BLOCK _PROCEDURE each-rental-space Procedure
312 PROCEDURE each-rental-space :
313 /*------------------------------------------------------------------------------
314 Purpose:
315 Parameters: <none>
316 ------------------------------------------------------------------------------*/
317 DEF INPUT PARAMETER rental-freq LIKE FrequencyType.FrequencyCode NO-UNDO.
318 DEF INPUT PARAMETER rental-fract AS DEC NO-UNDO.
319 DEF INPUT PARAMETER monthly-lease AS LOGI NO-UNDO.
320 DEF INPUT PARAMETER d-start AS DATE NO-UNDO.
321 DEF INPUT PARAMETER d-end AS DATE NO-UNDO.
322 DEF INPUT PARAMETER review-list AS CHAR NO-UNDO.
324 DEF VAR rent-amount AS DEC NO-UNDO.
325 DEF VAR base-rental AS DEC NO-UNDO.
326 DEF VAR rent-account AS DEC NO-UNDO.
327 DEF VAR rent-desc AS CHAR NO-UNDO.
328 DEF VAR start-date AS DATE NO-UNDO.
329 DEF VAR end-date AS DATE NO-UNDO.
330 DEF VAR re-lease-length AS INT NO-UNDO.
331 DEF VAR re-lease-delay AS INT NO-UNDO.
332 DEF VAR final-date AS DATE NO-UNDO.
333 DEF VAR mkt-rent AS DEC NO-UNDO.
334 DEF VAR mkt-date AS DATE NO-UNDO.
335 DEF VAR cf-desc AS CHAR NO-UNDO.
336 DEF VAR vacant AS LOGICAL NO-UNDO.
337 DEF VAR rent-modifiers AS CHAR NO-UNDO.
338 vacant = NOT AVAILABLE(TenancyLease).
340 IF LOOKUP(RentalSpace.AreaType, exclude-areas) > 0 THEN RETURN.
342 /* Check to ensure we haven't already created cashflows for this space because
343 * it is both attached to a lease _and_ marked as vacant (naughty!).
345 IF vacant AND CAN-FIND( FIRST CashFlow NO-LOCK WHERE CashFlow.ScenarioCode = Scenario.ScenarioCode
346 AND CashFlow.RelatedKey = id-code("RSP") AND CashFlow.CashFlowType = "RENT"
347 USE-INDEX XAK2CashFlow) THEN RETURN.
349 final-date = forecast-end.
350 re-lease-length = IF monthly-lease THEN monthly-length ELSE def-re-lease-length.
351 re-lease-delay = def-re-lease-delay.
352 rent-modifiers = "Property|" + STRING(Property.PropertyCode)
353 + ",Region|" + Property.Region
354 + ",Type|" + RentalSpace.AreaType .
356 rent-account = control-rent-account.
357 IF rent-charge-type = "Accounts" THEN DO:
358 FIND AreaType OF RentalSpace NO-LOCK NO-ERROR.
359 IF AVAILABLE AreaType THEN rent-account = AreaType.AccountCode.
360 END.
361 IF NOT CAN-FIND( ChartOfAccount WHERE ChartOfAccount.AccountCode = rent-account) THEN
362 rent-account = def-rent-account.
364 start-date = d-start.
365 end-date = d-end.
366 IF vacant THEN DO:
367 IF d-end > forecast-start THEN ASSIGN
368 start-date = forecast-start
369 end-date = d-end.
370 ELSE IF re-lease-delay < 1 THEN ASSIGN
371 start-date = add-months( first-of-month((IF RentalSpace.VacationDate = ? THEN TODAY ELSE RentalSpace.VacationDate)), 1)
372 end-date = ?.
373 ELSE ASSIGN
374 start-date = add-months( first-of-month((IF RentalSpace.VacationDate = ? THEN TODAY ELSE RentalSpace.VacationDate)), re-lease-delay)
375 /* start-date = add-months( first-of-month(TODAY), RANDOM( 1, re-lease-delay + 1)) */
376 end-date = ?.
377 IF start-date = ? OR start-date < forecast-start THEN
378 start-date = forecast-start.
379 END.
380 ELSE IF monthly-lease THEN DO:
381 IF d-start = ? THEN ASSIGN
382 start-date = forecast-start
383 end-date = ?.
384 ELSE ASSIGN
385 start-date = d-start
386 end-date = next-date-after( d-start, TODAY, "M", monthly-length ).
387 END.
389 cf-desc = STRING( RentalSpace.Level, "->9" ) + ", "
390 + STRING( RentalSpace.LevelSequence, ">>9" ) + " - "
391 + RentalSpace.Description.
393 RUN get-market-rent( start-date, OUTPUT mkt-rent, OUTPUT mkt-date).
394 IF vacant THEN DO:
395 rent-amount = get-new-rental( start-date, mkt-rent, mkt-date, rent-modifiers, OUTPUT cf-desc ).
396 cf-desc = "Lease at " + cf-desc.
397 END.
398 ELSE
399 rent-amount = - RentalSpace.ContractedRental .
401 IF AVAILABLE(TenancyLease) THEN DO:
402 FIND FIRST Tenant OF TenancyLease NO-LOCK NO-ERROR.
403 IF AVAILABLE(Tenant) THEN
404 cf-desc = "Lease by " + Tenant.Name .
405 END.
407 base-rental = rent-amount.
409 DO TRANSACTION:
410 DO WHILE start-date <= final-date:
411 IF end-date = ? OR end-date <= start-date THEN DO:
412 end-date = add-months( start-date, re-lease-length ) - 1.
413 review-list = reviews-from( start-date, end-date, review-months).
414 END.
415 RUN create-flow( "RENT", "N", rent-account, start-date,
416 (IF include-reviews AND review-list <> "" THEN (DATE(ENTRY(1,review-list)) - 1) ELSE end-date),
417 "MNTH", ROUND(rent-amount / 12, 2), cf-desc, id-code("RSP")).
419 IF include-reviews THEN DO WHILE review-list <> "" :
420 start-date = DATE(ENTRY(1,review-list)).
421 review-list = SUBSTRING( review-list, 12).
422 rent-amount = get-new-rental( start-date, mkt-rent, mkt-date, rent-modifiers, OUTPUT rent-desc ).
423 IF apply-ratchets AND rent-amount < base-rental THEN DO:
424 rent-amount = base-rental.
425 rent-desc = "base rent - ratchet clause applied".
426 END.
427 RUN create-flow( "RENT", "R", rent-account, start-date,
428 (IF review-list <> "" THEN (DATE(ENTRY(1,review-list)) - 1) ELSE end-date),
429 "MNTH", ROUND(rent-amount / 12, 2),
430 "Review to " + rent-desc, id-code("RSP")).
431 END.
433 IF include-releasing AND end-date <= final-date THEN DO:
434 start-date = add-months( end-date, re-lease-delay ) + 1.
436 IF re-lease-delay > 0 THEN DO:
437 IF ENTRY( 2, cf-desc, " ") = "by" THEN
438 cf-desc = SUBSTRING( cf-desc, 2).
439 ELSE
440 cf-desc = SUBSTRING( cf-desc, 2, INDEX( cf-desc, " p.a. based on Mkt: ") + 4).
441 cf-desc = "Vacant period after l" + cf-desc.
443 RUN create-flow( "RENT", "X", rent-account, end-date + 1, start-date - 1,
444 "MNTH", 0, cf-desc, id-code("RSP")).
445 END.
447 rent-amount = get-new-rental( start-date, mkt-rent, mkt-date, rent-modifiers, OUTPUT cf-desc ).
448 base-rental = rent-amount.
449 cf-desc = "Lease at " + cf-desc.
450 END.
451 ELSE
452 start-date = final-date + 1.
453 END.
454 END.
455 END PROCEDURE.
457 /* _UIB-CODE-BLOCK-END */
458 &ANALYZE-RESUME
461 &ANALYZE-SUSPEND _UIB-CODE-BLOCK _PROCEDURE each-tenancy-lease Procedure
462 PROCEDURE each-tenancy-lease :
463 /*------------------------------------------------------------------------------
464 Purpose:
465 Parameters: <none>
466 Notes:
467 ------------------------------------------------------------------------------*/
468 DEF VAR rental-freq AS CHAR NO-UNDO.
469 DEF VAR rental-fract AS DEC NO-UNDO.
470 DEF VAR monthly-lease AS LOGI NO-UNDO.
471 DEF VAR review-list AS CHAR NO-UNDO.
473 rental-freq = IF CAN-FIND( FIRST FrequencyType WHERE
474 FrequencyType.FrequencyCode = TenancyLease.PaymentFrequency ) THEN
475 TenancyLease.PaymentFrequency ELSE "MNTH".
476 RUN process/calcfreq.p ( rental-freq, OUTPUT rental-fract ).
477 monthly-lease = TenancyLease.LeaseEndDate = ? OR TenancyLease.LeaseEndDate < TODAY.
479 review-list = "".
480 FOR EACH RentReview NO-LOCK OF TenancyLease WHERE ReviewStatus <> "DONE"
481 AND RentReview.DateDue >= forecast-start
482 AND RentReview.DateDue <= forecast-end:
483 review-list = review-list + STRING( RentReview.DateDue, "99/99/9999") + ",".
484 END.
486 FOR EACH RentalSpace NO-LOCK OF TenancyLease:
487 RUN each-rental-space( rental-freq, rental-fract, monthly-lease,
488 TenancyLease.LeaseStartDate, TenancyLease.LeaseEndDate, review-list ).
489 END.
492 END PROCEDURE.
494 /* _UIB-CODE-BLOCK-END */
495 &ANALYZE-RESUME
498 &ANALYZE-SUSPEND _UIB-CODE-BLOCK _PROCEDURE get-growth-parameters Procedure
499 PROCEDURE get-growth-parameters :
500 /*------------------------------------------------------------------------------
501 Purpose:
502 ------------------------------------------------------------------------------*/
503 DEF VAR yy AS INT NO-UNDO.
504 DEF VAR pc-diff AS DEC NO-UNDO INITIAL 0.00 .
507 ASSIGN base-growth = to-number( get-parameter( "Growth" ) ) NO-ERROR.
508 IF base-growth = ? THEN base-growth = 0.
509 base-growth = 1 + base-growth.
511 FOR EACH ScenarioParameter NO-LOCK OF Scenario
512 WHERE ScenarioParameter.ParameterID BEGINS "Growth-":
513 CREATE delta-i.
514 delta-i.type = ENTRY( 2, ScenarioParameter.ParameterID, "-").
515 delta-i.subtype = ENTRY( 3, ScenarioParameter.ParameterID, "-").
516 delta-i.pc = 1 + to-number( ScenarioParameter.Data ).
517 debug-event( "Parameter " + ScenarioParameter.ParameterID + "=" + ScenarioParameter.Data ).
518 END.
520 pc-diff = base-growth.
521 DO yy = YEAR(forecast-start) TO YEAR(forecast-end):
522 FIND FIRST delta-i WHERE delta-i.type = "Year"
523 AND delta-i.subtype = STRING(yy,"9999") NO-ERROR.
524 IF AVAILABLE(delta-i) THEN
525 pc-diff = base-growth + delta-i.pc - 1.
526 ELSE DO:
527 CREATE delta-i.
528 delta-i.type = "Year".
529 delta-i.subtype = STRING(yy,"9999").
530 END.
531 delta-i.pc = pc-diff.
532 END.
534 FOR EACH delta-i:
535 debug-event( STRING( delta-i.type, "X(12)")
536 + STRING( delta-i.subtype, "X(12)")
537 + STRING( delta-i.pc, ">,>>9.9999") ).
538 END.
540 END PROCEDURE.
542 /* _UIB-CODE-BLOCK-END */
543 &ANALYZE-RESUME
546 &ANALYZE-SUSPEND _UIB-CODE-BLOCK _PROCEDURE get-market-rent Procedure
547 PROCEDURE get-market-rent :
548 /*------------------------------------------------------------------------------
549 Purpose:
550 ------------------------------------------------------------------------------*/
551 DEF INPUT PARAMETER start-date AS DATE NO-UNDO.
552 DEF OUTPUT PARAMETER mkt-rent AS DEC NO-UNDO.
553 DEF OUTPUT PARAMETER mkt-date AS DATE NO-UNDO.
555 mkt-rent = RentalSpace.MarketRental.
556 mkt-date = RentalSpace.MarketRentalDate.
558 IF market-per-unit THEN DO:
559 FIND AreaType OF RentalSpace NO-LOCK NO-ERROR.
560 IF AVAILABLE(AreaType) THEN DO:
561 mkt-rent = mkt-rent / 100.0 .
562 IF AreaType.IsFloorArea THEN
563 mkt-rent = mkt-rent * Property.MarketRental * RentalSpace.AreaSize.
564 ELSE IF AreaType.IsCarPark THEN
565 mkt-rent = mkt-rent * Property.MarketCarpark * (IF parks-per-month THEN 12 ELSE 52) * RentalSpace.AreaSize.
566 ELSE
567 mkt-rent = RentalSpace.ContractedRental.
568 END.
569 mkt-date = market-date.
570 RETURN.
571 END.
573 IF mkt-date <> ? AND mkt-date < DATE( 1, 1, 70) THEN
574 mkt-date = add-date( mkt-date, 2000, 0, 0).
576 IF mkt-date <> ? AND mkt-date < DATE( 1, 1, 200) THEN
577 mkt-date = add-date( mkt-date, 1900, 0, 0).
579 IF mkt-date = ? OR mkt-rent = 0 THEN DO:
580 mkt-rent = RentalSpace.ContractedRental.
581 mkt-date = start-date.
582 IF AVAILABLE(TenancyLease) THEN DO:
583 FIND LAST RentReview NO-LOCK OF TenancyLease WHERE RentReview.ReviewStatus = "DONE" NO-ERROR.
584 IF AVAILABLE(RentReview) AND mkt-date < RentReview.DateDue THEN
585 mkt-date = RentReview.DateDue.
586 ELSE IF mkt-date < (forecast-start - 400) THEN
587 mkt-date = forecast-start.
588 END.
589 IF mkt-date < (forecast-start - 1100) THEN
590 mkt-date = forecast-start.
591 END.
593 END PROCEDURE.
595 /* _UIB-CODE-BLOCK-END */
596 &ANALYZE-RESUME
599 &ANALYZE-SUSPEND _UIB-CODE-BLOCK _PROCEDURE get-parameters Procedure
600 PROCEDURE get-parameters :
601 /*------------------------------------------------------------------------------
602 Purpose:
603 ------------------------------------------------------------------------------*/
605 entity-list = get-parameter( "In-Entities" ).
606 ASSIGN entity-list-type = ENTRY( 1, entity-list)
607 entity-list-by = ENTRY( 2, entity-list)
608 entity-list = SUBSTRING( entity-list, LENGTH(entity-list-by) + 3)
609 all-entities = entity-list = "ALL" NO-ERROR .
610 IF entity-list = ? OR entity-list-by = ? OR entity-list-type = ? THEN DO:
611 MESSAGE "No Entity Filter for Scenario" VIEW-AS ALERT-BOX ERROR
612 TITLE "Regeneration Failed".
613 RETURN "FAIL".
614 END.
616 forecast-start = DATE( get-parameter( "Forecast-Start" ) ).
617 IF forecast-start = ? THEN forecast-start = DATE( 1, 1, YEAR(TODAY)).
618 forecast-end = DATE( get-parameter( "Forecast-End" ) ).
619 IF forecast-end = ? THEN forecast-end = add-date( TODAY, 11, 0, 0 ).
620 market-date = DATE( get-parameter( "market-date" ) ).
621 IF market-date = ? THEN market-date = forecast-start.
623 exclude-areas = get-parameter( "Exclude-Areas" ).
624 exclude-contracts = get-parameter( "Exclude-Contracts" ).
625 include-vacant-space = get-logical-parameter( "Vacant-Space" ).
626 include-releasing = get-logical-parameter( "Re-Leasing" ).
627 CASE SUBSTRING( TRIM(get-parameter( "Rent-Reviews" )), 1, 1):
628 WHEN "Y" THEN ASSIGN include-reviews = Yes apply-ratchets = No.
629 WHEN "R" THEN ASSIGN include-reviews = Yes apply-ratchets = Yes.
630 OTHERWISE ASSIGN include-reviews = No apply-ratchets = No.
631 END CASE.
633 RUN get-growth-parameters.
635 ASSIGN def-re-lease-length = INT( get-parameter( "Re-Lease-Length" ) ) NO-ERROR.
636 ASSIGN def-re-lease-delay = INT( get-parameter( "Re-Lease-Delay" ) ) NO-ERROR.
637 ASSIGN review-months = INT( get-parameter( "Review-Months" ) ) NO-ERROR.
638 ASSIGN monthly-length = INT( get-parameter( "Monthly-Length" ) ) NO-ERROR.
639 IF def-re-lease-length = ? THEN def-re-lease-length = 72.
640 IF def-re-lease-delay = ? THEN def-re-lease-delay = 3.
641 IF monthly-length = 0 OR monthly-length = ? THEN monthly-length = 24.
642 IF NOT ( review-months > 0 ) THEN review-months = 24.
644 def-rent-account = DEC( get-parameter("Default-RentAccount" ) ) NO-ERROR.
645 def-contract-account = DEC( get-parameter("Default-ContractAccount" ) ) NO-ERROR.
647 END PROCEDURE.
649 /* _UIB-CODE-BLOCK-END */
650 &ANALYZE-RESUME
653 &ANALYZE-SUSPEND _UIB-CODE-BLOCK _PROCEDURE parse-options Procedure
654 PROCEDURE parse-options :
655 /*------------------------------------------------------------------------------
656 Purpose: Decode the command-line parameters
657 ------------------------------------------------------------------------------*/
658 DEF VAR i AS INT NO-UNDO.
659 DEF VAR token AS CHAR NO-UNDO.
661 scenario-code = INT( ENTRY( 1, process-options , "~n") ).
663 DO i = 2 TO NUM-ENTRIES( process-options, "~n" ):
664 token = ENTRY( i, process-options, "~n" ).
665 CASE( ENTRY( 1, token ) ):
666 WHEN "Debug" THEN debug-mode = Yes.
667 WHEN "DoRentals" THEN do-rentals = Yes.
668 WHEN "DoService" THEN do-service = Yes.
669 END CASE.
670 END.
672 END PROCEDURE.
674 /* _UIB-CODE-BLOCK-END */
675 &ANALYZE-RESUME
678 &ANALYZE-SUSPEND _UIB-CODE-BLOCK _PROCEDURE rental Procedure
679 PROCEDURE rental :
680 /*------------------------------------------------------------------------------
681 Purpose:
682 Parameters: <none>
683 Notes:
684 ------------------------------------------------------------------------------*/
686 FOR EACH Property NO-LOCK:
687 IF NOT include-property() THEN NEXT.
689 debug-event( "Rental contracts for P" + STRING(Property.PropertyCode) + " - " + Property.Name ).
690 FOR EACH TenancyLease OF Property WHERE TenancyLease.LeaseStatus <> "PAST" NO-LOCK:
691 RUN each-tenancy-lease.
692 END.
694 IF include-vacant-space THEN DO:
695 debug-event( "Vacant space for P" + STRING(Property.PropertyCode) + " - " + Property.Name ).
696 FOR EACH RentalSpace NO-LOCK OF Property WHERE RentalSpace.AreaStatus = "V":
697 RUN each-rental-space( "MNTH", 0.0833333333, No, ?, RentalSpace.VacationDate, "" ).
698 END.
699 END.
701 END.
703 END PROCEDURE.
705 /* _UIB-CODE-BLOCK-END */
706 &ANALYZE-RESUME
709 &ANALYZE-SUSPEND _UIB-CODE-BLOCK _PROCEDURE service-contracts Procedure
710 PROCEDURE service-contracts :
711 /*------------------------------------------------------------------------------
712 Purpose:
713 Parameters: <none>
714 Notes:
715 ------------------------------------------------------------------------------*/
716 DEF VAR include-estimates AS LOGI NO-UNDO.
717 include-estimates = get-parameter( "Contract-Estimates" ) = "Yes".
718 DEF VAR description AS CHAR NO-UNDO.
719 DEF VAR contract-account AS DEC NO-UNDO.
720 DEF VAR contract-start AS DATE NO-UNDO.
721 DEF VAR contract-end AS DATE NO-UNDO.
722 DEF VAR period-divisor AS DEC NO-UNDO.
723 DEF VAR period-months AS INT NO-UNDO.
724 DEF VAR period-days AS INT NO-UNDO.
726 FOR EACH Property NO-LOCK:
727 IF NOT include-property() THEN NEXT.
728 debug-event( "Service contracts for P" + STRING(Property.PropertyCode) + " - " + Property.Name ).
729 FOR EACH Contract OF Property NO-LOCK WHERE
730 ( IF include-estimates THEN True ELSE ( NOT Contract.ServiceType BEGINS "EST" ) ),
731 FIRST ServiceType OF Contract NO-LOCK,
732 FIRST Creditor NO-LOCK WHERE Contract.CreditorCode = Creditor.CreditorCode:
734 IF NOT include-contract() THEN NEXT.
736 description = Creditor.Name.
737 IF TRIM(Contract.ContractReference) <> "" THEN
738 description = description + " - " + Contract.ContractReference .
740 IF Contract.Recoverable THEN
741 contract-account = ServiceType.AccountCode.
742 ELSE
743 contract-account = ServiceType.NRAccountCode.
745 IF NOT CAN-FIND( ChartOfAccount WHERE ChartOfAccount.AccountCode = contract-account) THEN
746 contract-account = def-contract-account.
748 period-months = get-freq-months( Contract.FrequencyCode ).
749 IF period-months = ? THEN ASSIGN
750 period-days = get-freq-days( Contract.FrequencyCode )
751 period-divisor = period-days / 365.
752 ELSE ASSIGN
753 period-days = ?
754 period-divisor = period-months / 12.
756 contract-start = (IF Contract.StartDate <> ? THEN Contract.StartDate ELSE forecast-start).
757 contract-end = (IF Contract.EndDate <> ? THEN Contract.EndDate ELSE forecast-end).
758 IF Contract.PaymentDate <> ? AND Contract.PaymentDate <> Contract.StartDate THEN DO:
759 contract-start = next-date-after( Contract.PaymentDate, contract-start,
760 (IF period-months <> ? THEN "M" ELSE "D"),
761 (IF period-months <> ? THEN period-months ELSE period-days)).
762 IF Contract.StartDate <> ? THEN DO:
763 contract-end = next-date-after( Contract.PaymentDate, contract-end,
764 (IF period-months <> ? THEN "M" ELSE "D"),
765 (IF period-months <> ? THEN period-months ELSE period-days)).
766 contract-end = contract-end - 1.
767 END.
768 END.
769 debug-event( "Cashflow for contract " + id-code("SCL") + ", " + Contract.FrequencyCode + ": "
770 + STRING( Contract.FixedAmount) + ", annual = "
771 + STRING( Contract.AnnualEstimate ) + ", start = "
772 + STRING( contract-start, "99/99/9999" ) ).
774 RUN create-flow( "SCL", "", contract-account, contract-start,
775 contract-end, Contract.FrequencyCode,
776 Contract.AnnualEstimate * period-divisor,
777 ServiceType.ServiceType + " - " + description, id-code("SCL") ).
779 IF Contract.Renewing THEN DO WHILE contract-end < forecast-end:
780 contract-end = renew-contract( contract-end + 1, id-code("SCL"),
781 contract-account, Contract.AnnualEstimate * period-divisor,
782 ServiceType.ServiceType + " - " + description ).
783 END.
784 END.
786 END.
788 END PROCEDURE.
790 /* _UIB-CODE-BLOCK-END */
791 &ANALYZE-RESUME
794 /* ************************ Function Implementations ***************** */
796 &ANALYZE-SUSPEND _UIB-CODE-BLOCK _FUNCTION check-manual-flow Procedure
797 FUNCTION check-manual-flow RETURNS LOGICAL
798 ( INPUT man-type AS CHAR, INPUT chg-type AS CHAR, INPUT id-cd AS CHAR, INPUT-OUTPUT d-1 AS DATE, INPUT-OUTPUT d-n AS DATE ) :
799 /*------------------------------------------------------------------------------
800 Purpose: Check that no manual cash flow occurs between d-1 and d-n
801 Notes: We adjust the dates if necessary, or perhaps we give up entirely
802 (i.e. RETURN No) if the whole period is occluded.
803 ------------------------------------------------------------------------------*/
804 DEF BUFFER OtherFlow FOR CashFlow.
806 /* Can't manually override adjustments, except by specifically overwriting the amounts */
807 IF chg-type = "A" THEN DO:
808 IF CAN-FIND( FIRST OtherFlow WHERE OtherFlow.ScenarioCode = Scenario.ScenarioCode
809 AND OtherFlow.RelatedKey = id-cd
810 AND OtherFlow.CashFlowType = man-type
811 AND OtherFlow.StartDate = d-1
812 AND OtherFlow.EndDate = d-n
813 AND OtherFlow.CFChangeType = "A") THEN
814 RETURN No.
815 ELSE
816 RETURN Yes.
817 END.
819 FOR EACH OtherFlow NO-LOCK WHERE OtherFlow.ScenarioCode = Scenario.ScenarioCode
820 AND OtherFlow.RelatedKey = id-cd
821 AND OtherFlow.CashFlowType = man-type
822 AND (OtherFlow.StartDate <= d-n OR OtherFlow.StartDate = ?)
823 AND (OtherFlow.EndDate >= d-1 OR OtherFlow.EndDate = ?):
825 IF (OtherFlow.StartDate <= d-1 OR OtherFlow.StartDate = ?)
826 AND (OtherFlow.EndDate >= d-n OR OtherFlow.EndDate = ?) THEN RETURN No.
828 IF OtherFlow.StartDate > d-1 THEN DO:
829 debug-event( id-cd + ": Adjusted flow end because of manual flow starting on " + STRING(OtherFlow.StartDate, "99/99/9999") ).
830 d-n = OtherFlow.StartDate - 1.
831 END.
832 ELSE IF OtherFlow.EndDate < d-n THEN DO:
833 debug-event( id-cd + ": Adjusted flow start because of manual flow ending on " + STRING(OtherFlow.EndDate, "99/99/9999") ).
834 d-1 = OtherFlow.EndDate + 1.
835 END.
837 END.
839 RETURN (d-1 <= d-n) OR d-1 = ? OR d-n = ?.
841 END FUNCTION.
843 /* _UIB-CODE-BLOCK-END */
844 &ANALYZE-RESUME
847 &ANALYZE-SUSPEND _UIB-CODE-BLOCK _FUNCTION get-growth Procedure
848 FUNCTION get-growth RETURNS DECIMAL
849 ( INPUT base-date AS DATE, INPUT change-date AS DATE, INPUT modifiers AS CHAR ) :
850 /*------------------------------------------------------------------------------
851 Purpose: Calculate the change in rent over time
852 ------------------------------------------------------------------------------*/
853 DEF VAR difference AS DECIMAL NO-UNDO.
854 DEF VAR real-growth AS DEC NO-UNDO INITIAL 1.0.
855 DEF VAR yy AS INT NO-UNDO.
856 DEF VAR i AS INT NO-UNDO.
857 DEF VAR mod-type AS CHAR NO-UNDO.
858 DEF VAR mod-subtype AS CHAR NO-UNDO.
860 IF change-date <= base-date THEN RETURN 1.0 .
862 IF debug-mode THEN
863 debug-event( modifiers + ": " + STRING(base-date,"99/99/9999") + " to " + STRING(change-date,"99/99/9999")).
865 yy = YEAR(base-date + 183).
866 difference = TRUNC( (change-date - base-date) / 365, 0) - 1.
867 IF difference >= 0 THEN DO i = yy TO yy + difference:
868 /* for whole years, compound the appropriate growth for that year */
869 FIND FIRST delta-i WHERE delta-i.type = "Year"
870 AND delta-i.subtype = STRING(i,"9999") NO-LOCK NO-ERROR.
871 real-growth = real-growth * (IF AVAILABLE(delta-i) THEN delta-i.pc ELSE base-growth).
873 IF debug-mode THEN
874 debug-event( "Year-" + STRING(i,"9999")
875 + ": compounded: " + STRING(real-growth)
876 + ", annual: " + STRING(IF AVAILABLE(delta-i) THEN delta-i.pc ELSE base-growth)
878 END.
880 difference = ((change-date - base-date) MOD 365).
881 IF difference > 4 THEN DO:
882 /* calculate the delta for the remaining part year */
883 yy = YEAR(change-date).
884 IF (difference / 2) > (change-date - DATE(1,1,yy)) THEN yy = yy - 1.
885 FIND FIRST delta-i WHERE delta-i.type = "Year"
886 AND delta-i.subtype = STRING(yy,"9999") NO-LOCK NO-ERROR.
887 difference = 1 + (((IF AVAILABLE(delta-i) THEN delta-i.pc ELSE base-growth ) - 1) * (difference / 365)).
888 real-growth = real-growth * difference.
890 IF debug-mode THEN
891 debug-event( "Year-" + STRING(yy,"9999")
892 + ": compounded: " + STRING(real-growth)
893 + ", annual: " + STRING( difference )
895 END.
897 yy = NUM-ENTRIES( modifiers ).
898 DO i = 1 TO yy:
899 /* apply any other modifiers */
900 mod-type = ENTRY( 1, ENTRY(i,modifiers), "|").
901 mod-subtype = ENTRY( 2, ENTRY(i,modifiers), "|").
902 FIND FIRST delta-i WHERE delta-i.type = mod-type
903 AND delta-i.subtype = mod-subtype NO-ERROR.
904 IF AVAILABLE(delta-i) THEN DO:
905 real-growth = real-growth * delta-i.pc.
907 IF debug-mode THEN
908 debug-event( delta-i.type + "-" + delta-i.subtype
909 + ": compounded: " + STRING(real-growth)
910 + ", annual: " + STRING(IF AVAILABLE(delta-i) THEN delta-i.pc ELSE 0)
912 END.
913 END.
915 RETURN real-growth.
917 END FUNCTION.
919 /* _UIB-CODE-BLOCK-END */
920 &ANALYZE-RESUME
923 &ANALYZE-SUSPEND _UIB-CODE-BLOCK _FUNCTION get-logical-parameter Procedure
924 FUNCTION get-logical-parameter RETURNS LOGICAL
925 ( INPUT parameter-id AS CHAR ) :
926 /*------------------------------------------------------------------------------
927 Purpose:
928 Notes:
929 ------------------------------------------------------------------------------*/
931 RETURN (SUBSTRING( get-parameter( parameter-id ), 1, 1) = "Y").
933 END FUNCTION.
935 /* _UIB-CODE-BLOCK-END */
936 &ANALYZE-RESUME
939 &ANALYZE-SUSPEND _UIB-CODE-BLOCK _FUNCTION get-new-rental Procedure
940 FUNCTION get-new-rental RETURNS DECIMAL
941 ( INPUT d-rent AS DATE, INPUT mkt-rent AS DEC, INPUT d-mkt AS DATE, INPUT modifiers AS CHAR, OUTPUT descr AS CHAR ) :
942 /*------------------------------------------------------------------------------
943 Purpose:
944 Notes:
945 ------------------------------------------------------------------------------*/
946 DEF VAR rnt-growth AS DEC NO-UNDO.
947 DEF VAR new-rent AS DEC NO-UNDO.
948 DEF VAR area-size AS DEC NO-UNDO.
950 DEF VAR new-rent-text AS CHAR NO-UNDO.
952 area-size = RentalSpace.AreaSize.
953 IF area-size = 0 OR area-size = ? THEN area-size = 1.
954 rnt-growth = get-growth( d-mkt, d-rent, modifiers).
955 new-rent = mkt-rent * rnt-growth.
956 IF NOT AVAILABLE(RentalSpace) THEN
957 new-rent-text = TRIM( STRING( new-rent, "->>,>>>,>>9.99")) + " pa".
958 ELSE IF RentalSpace.AreaType = "C" THEN
959 new-rent-text = TRIM( STRING( ((new-rent / area-size) / 52), "->>,>>>,>>9.99")) + "/pk/wk".
960 ELSE
961 new-rent-text = TRIM( STRING( (new-rent / area-size), "->>,>>>,>>9.99")) + " psm".
963 IF market-per-unit THEN DO:
964 descr = new-rent-text
965 + " based on Mkt: " + TRIM( STRING( mkt-rent, "->>,>>>,>>9.99")).
966 FIND AreaType OF RentalSpace NO-LOCK NO-ERROR.
967 IF AVAILABLE(AreaType) THEN DO:
968 mkt-rent = RentalSpace.MarketRental / 100.0 .
969 IF AreaType.IsFloorArea THEN
970 descr = descr + " (" + TRIM( STRING(mkt-rent * Property.MarketRental, "->>,>>>,>>9.99")) + " per " + area-units + ") ".
971 ELSE IF AreaType.IsCarPark THEN
972 descr = descr + " (" + TRIM( STRING(mkt-rent * Property.MarketCarpark, "->>,>>>,>>9.99")) + " per Pk/" + (IF parks-per-month THEN "Mth" ELSE "Wk") + ") ".
973 END.
974 descr = descr + ", grown by " + TRIM(STRING((rnt-growth * 100) - 100,"->>,>>9.99")) + "%".
975 END.
976 ELSE
977 descr = new-rent-text
978 + " based on Mkt: " + TRIM( STRING( mkt-rent, "->>,>>>,>>9.99"))
979 + " at " + STRING( d-mkt, "99/99/9999")
980 + " - growth of " + TRIM(STRING((rnt-growth * 100) - 100,"->>,>>9.99")) + "%".
982 RETURN - new-rent.
984 END FUNCTION.
986 /* _UIB-CODE-BLOCK-END */
987 &ANALYZE-RESUME
990 &ANALYZE-SUSPEND _UIB-CODE-BLOCK _FUNCTION get-parameter Procedure
991 FUNCTION get-parameter RETURNS CHARACTER
992 ( INPUT parameter-name AS CHAR ) :
993 /*------------------------------------------------------------------------------
994 Purpose:
995 Notes:
996 ------------------------------------------------------------------------------*/
997 IF NOT AVAILABLE Scenario THEN RETURN "".
999 DEF VAR dv AS CHAR NO-UNDO.
1001 FIND FIRST ScenarioParameter OF Scenario WHERE
1002 ScenarioParameter.ParameterID = parameter-name NO-LOCK NO-ERROR.
1004 dv = ( IF AVAILABLE ScenarioParameter THEN ScenarioParameter.Data ELSE "" ).
1005 debug-event( "Parameter " + parameter-name + "=" + dv ).
1007 RETURN dv.
1009 END FUNCTION.
1011 /* _UIB-CODE-BLOCK-END */
1012 &ANALYZE-RESUME
1015 &ANALYZE-SUSPEND _UIB-CODE-BLOCK _FUNCTION id-code Procedure
1016 FUNCTION id-code RETURNS CHARACTER
1017 ( INPUT type AS CHAR ) :
1018 /*------------------------------------------------------------------------------
1019 Purpose:
1020 Notes: Record appropriate to type must be available
1021 ------------------------------------------------------------------------------*/
1022 IF type = "TLS" AND AVAILABLE(TenancyLease) THEN
1023 RETURN "TLS," + STRING( TenancyLease.TenancyLeaseCode, "99999" ).
1024 ELSE IF AVAILABLE(RentalSpace) THEN
1025 RETURN "RSP," + STRING( RentalSpace.PropertyCode, "99999" )
1026 + ",L," + STRING( 50000 + RentalSpace.Level, "99999" )
1027 + ",S," + STRING( 50000 + RentalSpace.LevelSequence, "99999" )
1028 + ",R," + STRING( RentalSpace.RentalSpaceCode ).
1029 ELSE IF AVAILABLE(Contract) THEN
1030 RETURN "SVC," + STRING( Contract.PropertyCode, "99999" )
1031 + ",T," + Contract.ServiceType
1032 + ",C," + STRING( Contract.CreditorCode, "99999" ).
1033 ELSE
1034 MESSAGE "Don't know how to make an id code - no appropriate records available".
1036 END FUNCTION.
1038 /* _UIB-CODE-BLOCK-END */
1039 &ANALYZE-RESUME
1042 &ANALYZE-SUSPEND _UIB-CODE-BLOCK _FUNCTION include-contract Procedure
1043 FUNCTION include-contract RETURNS LOGICAL
1044 ( /* parameter-definitions */ ) :
1045 /*------------------------------------------------------------------------------
1046 Purpose:
1047 Notes:
1048 ------------------------------------------------------------------------------*/
1050 RETURN ( IF exclude-contracts = "ALL" THEN No ELSE
1051 LOOKUP( Contract.ServiceType, exclude-contracts ) < 1 ).
1053 END FUNCTION.
1055 /* _UIB-CODE-BLOCK-END */
1056 &ANALYZE-RESUME
1059 &ANALYZE-SUSPEND _UIB-CODE-BLOCK _FUNCTION include-property Procedure
1060 FUNCTION include-property RETURNS LOGICAL
1061 ( /* parameter-definitions */ ) :
1062 /*------------------------------------------------------------------------------
1063 Purpose:
1064 Notes:
1065 ------------------------------------------------------------------------------*/
1066 DEF VAR include-it AS LOGI NO-UNDO.
1068 IF all-entities THEN RETURN Property.Active .
1069 IF entity-list-type <> "P" THEN RETURN No.
1071 CASE entity-list-by:
1072 WHEN "Company" THEN
1073 include-it = LOOKUP( STRING( Property.PropertyCode ), entity-list ) <> 0.
1075 WHEN "Properties" THEN
1076 include-it = LOOKUP( STRING( Property.PropertyCode ), entity-list ) <> 0.
1078 WHEN "Property Managers" THEN
1079 include-it = LOOKUP( STRING( Property.Administrator ), entity-list ) <> 0.
1081 WHEN "Portfolios" THEN
1082 include-it = LOOKUP( STRING( Property.Manager ), entity-list ) <> 0.
1084 WHEN "Regions" THEN
1085 include-it = LOOKUP( Property.Region, entity-list ) <> 0.
1086 END CASE.
1088 RETURN include-it.
1090 END FUNCTION.
1092 /* _UIB-CODE-BLOCK-END */
1093 &ANALYZE-RESUME
1096 &ANALYZE-SUSPEND _UIB-CODE-BLOCK _FUNCTION renew-contract Procedure
1097 FUNCTION renew-contract RETURNS DATE
1098 ( INPUT start-date AS DATE, INPUT relation AS CHAR, INPUT ac AS DEC, INPUT amt AS DEC, INPUT description AS CHAR ) :
1099 /*------------------------------------------------------------------------------
1100 Purpose:
1101 Notes:
1102 ------------------------------------------------------------------------------*/
1103 DEF VAR end-date AS DATE NO-UNDO.
1105 debug-event( "Renewing contract " + relation + ", " + Contract.FrequencyCode + ": " + STRING( amt) ).
1107 end-date = add-months( start-date - 1, 12).
1108 RUN create-flow( "SCL", "", ac, start-date, end-date, Contract.FrequencyCode, amt, description, id-code("SCL") ).
1110 RETURN end-date .
1112 END FUNCTION.
1114 /* _UIB-CODE-BLOCK-END */
1115 &ANALYZE-RESUME
1118 &ANALYZE-SUSPEND _UIB-CODE-BLOCK _FUNCTION reviews-from Procedure
1119 FUNCTION reviews-from RETURNS CHARACTER
1120 ( INPUT d-1 AS DATE, INPUT d-n AS DATE, INPUT months AS INT ) :
1121 /*------------------------------------------------------------------------------
1122 Purpose: Create a list of rent review dates between d-1 and d-n.
1123 Notes:
1124 ------------------------------------------------------------------------------*/
1125 DEF VAR review-list AS CHAR NO-UNDO.
1127 d-1 = add-months( d-1, months).
1128 DO WHILE d-1 < d-n:
1129 review-list = review-list + STRING( d-1, "99/99/9999") + ",".
1130 d-1 = add-months( d-1, months).
1131 END.
1133 RETURN review-list.
1135 END FUNCTION.
1137 /* _UIB-CODE-BLOCK-END */
1138 &ANALYZE-RESUME
1141 &ANALYZE-SUSPEND _UIB-CODE-BLOCK _FUNCTION to-number Procedure
1142 FUNCTION to-number RETURNS DECIMAL
1143 ( INPUT txtnum AS CHAR ) :
1144 /*------------------------------------------------------------------------------
1145 Purpose: Convert a text value into a number
1146 Notes:
1147 ------------------------------------------------------------------------------*/
1148 DEF VAR result AS DEC NO-UNDO.
1149 DEF VAR bare AS CHAR NO-UNDO.
1150 DEF VAR negative AS LOGI NO-UNDO INITIAL No.
1152 bare = REPLACE(txtnum, '"', "").
1153 bare = REPLACE(bare, '$', "").
1154 bare = REPLACE(bare, ',', "").
1155 bare = REPLACE(bare, '%', "").
1156 bare = REPLACE(bare, ';', "").
1157 bare = REPLACE(bare, ' ', "").
1158 bare = REPLACE(bare, '<', "").
1159 bare = REPLACE(bare, 'C', "").
1160 bare = REPLACE(bare, 'R', "").
1161 bare = REPLACE(bare, 'D', "").
1162 bare = REPLACE(bare, 'B', "").
1163 bare = REPLACE(bare, '-', "").
1164 bare = REPLACE(bare, '(', "").
1165 IF (INDEX(txtnum, "CR") > 0) THEN negative = Yes.
1166 IF (INDEX(txtnum, "DB") > 0) THEN negative = No.
1167 IF (INDEX(txtnum, "-") > 0) THEN negative = Yes.
1168 IF (INDEX(txtnum, "<") > 0) THEN negative = Yes.
1169 IF (INDEX(txtnum, "(") > 0) THEN negative = Yes.
1170 result = DEC(bare).
1171 IF negative THEN result = result * -1 .
1172 IF INDEX( txtnum, "%") > 0 THEN result = result / 100.
1174 RETURN result.
1176 END FUNCTION.
1178 /* _UIB-CODE-BLOCK-END */
1179 &ANALYZE-RESUME