| Quintiq file version 2.0 | 
| #parent: #root | 
| StaticMethod ValidateInput ( | 
|   output Strings feedback_o, | 
|   output Strings sanitycheckfeedback_o, | 
|   MacroPlan macroplan, | 
|   Product_MP product, | 
|   StockingPoint_MP stockingpoint, | 
|   ActualProductInStockingPointInPeriod actualpispip, | 
|   Real actualinventorylevelend, | 
|   Date date, | 
|   Date manufactureddate | 
| ) declarative remote as Boolean | 
| { | 
|   Description: 'Validate input for actual pispip' | 
|   TextBody: | 
|   [* | 
|     isvalid := true; | 
|      | 
|     feedback := ''; | 
|     sanitycheckfeedback := ''; | 
|      | 
|     // Has product | 
|     if( isnull( product ) ) | 
|     { | 
|       feedback := Translations::MP_ActualProductInStockingPointInPeriod_ValidateInput_IsNullProduct(); | 
|       sanitycheckfeedback := SanityCheckCategoryLevel::GetSanityCheckCategoryDataIssue(); | 
|     } | 
|     // Has stocking point | 
|     else if( isnull( stockingpoint ) ) | 
|     { | 
|       feedback := Translations::MP_ActualProductInStockingPointInPeriod_ValidateInput_IsNullStockingPoint(); | 
|       sanitycheckfeedback := SanityCheckCategoryLevel::GetSanityCheckCategoryDataIssue(); | 
|     } | 
|     else | 
|     { | 
|       planningperiodstart := macroplan.StartOfPlanning().Date(); | 
|       pisp := select( product, ProductInStockingPoint_MP, p, p.StockingPoint_MP() = stockingpoint ); | 
|          | 
|       // set mfg date to MinDate if the product has no shelf life or maturation and not isExludeShelfLifeAndMaturation | 
|       hasshelflife := product.HasShelfLife() | 
|                       and guard( not pisp.PISPSpecification().IsExcludeShelfLifeAndMaturation(), true ); | 
|                        | 
|       hasshelflifeormaturation := product.HasShelfLifeOrMaturation() | 
|                       and guard( not pisp.PISPSpecification().IsExcludeShelfLifeAndMaturation(), true );                 | 
|                        | 
|       manufactureddate := ifexpr( hasshelflifeormaturation, manufactureddate, Date::MinDate() ); | 
|        | 
|       uniqueidentifier := ActualProductInStockingPointInPeriod::GetUniqueIdentifier( product.ID(), stockingpoint.ID(), date, product.HasShelfLifeOrMaturation(), manufactureddate ); | 
|        | 
|       minimummanufactureddate := ActualProductInStockingPointInPeriod::GetMinimumManufacturedDate( product, stockingpoint, date ); | 
|        | 
|       // Check uniqueness | 
|       // Check if 'checkunique' = true and if there are any actuals with same type index | 
|       if( not isnull( pisp ) | 
|           and exists( pisp, ActualProductInStockingPointInPeriod, a2, | 
|                       actualpispip <> a2, | 
|                       a2.GetUniqueIdentifier() = uniqueidentifier ) ) | 
|       { | 
|         // manufactured date text only needed for product with shelflife/maturation | 
|         manufactureddatetext := ifexpr( hasshelflife,  | 
|                                         Translations::MP_ActualProductInStockingPointInPeriod_ValidateInput_IsNotUnique_ManufacturedDateText( manufactureddate ), | 
|                                         '' ); | 
|         feedback := Translations::MP_ActualProductInStockingPointInPeriod_ValidateInput_IsNotUnique( manufactureddatetext ); | 
|         sanitycheckfeedback := SanityCheckCategoryLevel::GetSanityCheckCategoryDataIssue(); | 
|       } | 
|        | 
|       // Validate negative input | 
|       else if( actualinventorylevelend < 0.0 ) | 
|       {  | 
|         feedback := Translations::MP_ActualProductInStockingPointInPeriod_ValidateInput_IsNegativeActualInventoryLevelEnd( actualinventorylevelend ); | 
|         sanitycheckfeedback := SanityCheckCategoryLevel::GetSanityCheckCategoryDataWarning(); | 
|       } | 
|       // Check if the provided date is within any periods, | 
|       // this is only used in GUI because the new GUI allows user to enter a date that is >= start of planning period | 
|       else if( date >= planningperiodstart ) | 
|       { | 
|         feedback := Translations::MP_ActualProductInStockingPointInPeriod_ValidateInput_IsValidDate( planningperiodstart ); | 
|         sanitycheckfeedback := SanityCheckCategoryLevel::GetSanityCheckCategoryDataIssue(); | 
|       } | 
|       // Check if product has shelf-life and will expire by the period | 
|       else if( hasshelflife | 
|                and manufactureddate < minimummanufactureddate )  | 
|       { | 
|         feedback := Translations::MP_ActualProductInStockingPointInPeriod_ValidateInput_IsExpiredManufacturedDate( manufactureddate, product.ShelfLife(), date ); | 
|         sanitycheckfeedback := SanityCheckCategoryLevel::GetSanityCheckCategoryDataWarning(); | 
|       } | 
|       // Check if product has shelf-life or maturation, and is manufactured in the future | 
|       else if( hasshelflifeormaturation  | 
|                and manufactureddate > date ) | 
|       { | 
|         feedback := Translations::MP_ActualProductInStockingPointInPeriod_ValidateInput_IsFutureManufacturedDate( manufactureddate, date ); | 
|         sanitycheckfeedback := SanityCheckCategoryLevel::GetSanityCheckCategoryDataIssue(); | 
|       } | 
|     } | 
|      | 
|     if( feedback <> '' ) | 
|     { | 
|       isvalid := false; | 
|       productname := MacroPlan::GetSubstituteName( guard( product.Name(), '' ) ); | 
|       stockingpointname := MacroPlan::GetSubstituteName( guard( stockingpoint.Name(), '' ) ); | 
|       instance := ActualProductInStockingPointInPeriod::GetInstanceText( productname, stockingpointname, date ); | 
|       feedback := SanityCheckMessage::GetFormattedMessage( instance, feedback ); | 
|        | 
|       feedback_o.Add( feedback ); | 
|       sanitycheckfeedback_o.Add( sanitycheckfeedback ); | 
|     } | 
|      | 
|     return isvalid; | 
|   *] | 
| } |