diff --git a/src/Apps/W1/ExpenseAgent/app/src/Setup/Codeunits/CreateExpenseCategories.Codeunit.al b/src/Apps/W1/ExpenseAgent/app/src/Setup/Codeunits/CreateExpenseCategories.Codeunit.al index 05b2c49c9ff..23caec182fb 100644 --- a/src/Apps/W1/ExpenseAgent/app/src/Setup/Codeunits/CreateExpenseCategories.Codeunit.al +++ b/src/Apps/W1/ExpenseAgent/app/src/Setup/Codeunits/CreateExpenseCategories.Codeunit.al @@ -101,8 +101,6 @@ codeunit 6973 "Create Expense Categories" AddPostingGroupSeed(TempPostingGroup, XEXPENSEMILEAGETxt, XExpenseMileageDescTxt, CreateExpenseGLAccount.ExpenseMileageRefundableDebitAccountNo()); AddPostingGroupSeed(TempPostingGroup, XEXPENSEMEALSTxt, XExpenseMealsDescTxt, CreateExpenseGLAccount.ExpenseMealsRefundableDebitAccountNo()); AddPostingGroupSeed(TempPostingGroup, XEXPENSEENTERTAINTxt, XExpenseEntertainDescTxt, CreateExpenseGLAccount.ExpenseEntertainRefundableDebitAccountNo()); - - OnAfterBuildPostingGroupSeeds(TempPostingGroup); end; /// @@ -136,13 +134,7 @@ codeunit 6973 "Create Expense Categories" end; internal procedure AddPostingGroupSeed(var TempPostingGroup: Record "Expense Posting Group" temporary; Code: Code[20]; Description: Text[100]; RefundableDebitAccount: Code[20]) - var - IsHandled: Boolean; begin - OnBeforeAddPostingGroupSeed(Code, Description, RefundableDebitAccount, IsHandled); - if IsHandled then - exit; - TempPostingGroup.Init(); TempPostingGroup.Code := Code; TempPostingGroup.Description := Description; @@ -151,7 +143,6 @@ codeunit 6973 "Create Expense Categories" TempPostingGroup."Prepayment Credit Account" := CreateExpenseGLAccount.ExpensePrepaymentDebitAccountNo(); TempPostingGroup."Debit Rounding Account" := CreateExpenseGLAccount.ExpenseDebitRoundingAccountNo(); TempPostingGroup."Credit Rounding Account" := CreateExpenseGLAccount.ExpenseCreditRoundingAccountNo(); - OnBeforeInsertPostingGroupSeed(TempPostingGroup); TempPostingGroup.Insert(); end; @@ -239,8 +230,6 @@ codeunit 6973 "Create Expense Categories" AddCategorySeed(TempCategory, XSUBSCRIPTIONTxt, XProfessionalSubscriptionsTxt, XSubscriptionsPostingTxt, XDAYEXPENSETxt, XEXPENSEOTHERTxt, XCARDTxt, true, false, "Expense Attachment Enforcement"::Warning, "Expense Detail Needed"::" "); AddCategorySeed(TempCategory, XTIPSTxt, XTipsDescTxt, XTipsPostingTxt, XFOODBEVERAGETxt, XEXPENSEOTHERTxt, XCASHTxt, false, false, "Expense Attachment Enforcement"::" ", "Expense Detail Needed"::" "); AddCategorySeed(TempCategory, XTOLLSTxt, XTollRoadUsageFeeTxt, XTollsPostingTxt, XDAYEXPENSETxt, XEXPENSEOTHERTxt, XCASHTxt, true, false, "Expense Attachment Enforcement"::Warning, "Expense Detail Needed"::" "); - - OnAfterBuildCategorySeeds(TempCategory); end; /// @@ -355,8 +344,6 @@ codeunit 6973 "Create Expense Categories" // FINES AddSubcategorySeed(TempSubcategory, XFINESTxt, XFINESTxt, XFinesSubDescTxt, XFinesPostingTxt, true, false); - - OnAfterBuildSubcategorySeeds(TempSubcategory); end; internal procedure GetTRAVELTxt(): Code[20] @@ -616,13 +603,7 @@ codeunit 6973 "Create Expense Categories" end; internal procedure AddCategorySeed(var TempCategory: Record "Expense Category" temporary; Code: Code[20]; Description: Text[250]; PostingDescription: Text[100]; ExpenseGroupCode: Code[20]; PostingGroupCode: Code[20]; PaymentMethod: Code[10]; IsRefundable: Boolean; IsPrepayment: Boolean; AttachmentEnforcement: Enum "Expense Attachment Enforcement"; DetailRequired: Enum "Expense Detail Needed") - var - IsHandled: Boolean; begin - OnBeforeAddCategorySeed(Code, Description, PostingDescription, ExpenseGroupCode, PostingGroupCode, PaymentMethod, IsRefundable, IsPrepayment, AttachmentEnforcement, DetailRequired, IsHandled); - if IsHandled then - exit; - TempCategory.Init(); TempCategory.Code := Code; TempCategory.Description := Description; @@ -638,13 +619,7 @@ codeunit 6973 "Create Expense Categories" end; internal procedure AddSubcategorySeed(var TempSubcategory: Record "Expense Subcategory" temporary; SubcategoryCode: Code[20]; CategoryCode: Code[20]; Description: Text[250]; PostingDescription: Text[100]; Refundable: Boolean; DescriptionMandatory: Boolean) - var - IsHandled: Boolean; begin - OnBeforeAddSubcategorySeed(SubcategoryCode, CategoryCode, Description, PostingDescription, Refundable, DescriptionMandatory, IsHandled); - if IsHandled then - exit; - TempSubcategory.Init(); TempSubcategory."Expense Category Code" := CategoryCode; TempSubcategory.Code := SubcategoryCode; @@ -828,8 +803,6 @@ codeunit 6973 "Create Expense Categories" AddRuleSeed(TempRuleHeader, XPERDIEMTxt, XGERMANYALLTxt, 'EUR', "Expense Justification"::" "); AddRuleSeed(TempRuleHeader, XPERDIEMTxt, XUKOTHERTxt, 'GBP', "Expense Justification"::" "); AddRuleSeed(TempRuleHeader, XPERDIEMTxt, XUSAOTHERTxt, 'USD', "Expense Justification"::" "); - - OnAfterBuildRuleSeeds(TempRuleHeader); end; /// @@ -850,8 +823,6 @@ codeunit 6973 "Create Expense Categories" AddRuleConditionSeed(TempRuleCondition, XPERDIEMTxt, XGERMANYALLTxt, "Expense Rule Condition Type"::"Daily Rate", 105); AddRuleConditionSeed(TempRuleCondition, XPERDIEMTxt, XUKOTHERTxt, "Expense Rule Condition Type"::"Daily Rate", 115); AddRuleConditionSeed(TempRuleCondition, XPERDIEMTxt, XUSAOTHERTxt, "Expense Rule Condition Type"::"Daily Rate", 120); - - OnAfterBuildRuleConditionSeeds(TempRuleCondition); end; /// @@ -933,31 +904,19 @@ codeunit 6973 "Create Expense Categories" end; internal procedure AddRuleSeed(var TempRuleHeader: Record "Expense Rule Header" temporary; CategoryCode: Code[20]; ExpenseLocationCode: Code[20]; CurrencyCode: Code[10]; JustificationRequired: Enum "Expense Justification") - var - IsHandled: Boolean; begin - OnBeforeAddRuleSeed(TempRuleHeader, CategoryCode, ExpenseLocationCode, CurrencyCode, JustificationRequired, IsHandled); - if IsHandled then - exit; - TempRuleHeader.Init(); TempRuleHeader."Expense Category Code" := CategoryCode; TempRuleHeader."Expense Location" := ExpenseLocationCode; TempRuleHeader."Currency Code" := CurrencyCode; TempRuleHeader."Justification Required" := JustificationRequired; - OnBeforeInsertRuleSeed(TempRuleHeader); TempRuleHeader.Insert(); end; internal procedure AddRuleConditionSeed(var TempRuleCondition: Record "Expense Rule Condition" temporary; CategoryCode: Code[20]; ExpenseLocationCode: Code[20]; ConditionType: Enum "Expense Rule Condition Type"; Value: Decimal) var NextLineNo: Integer; - IsHandled: Boolean; begin - OnBeforeAddRuleConditionSeed(TempRuleCondition, CategoryCode, ExpenseLocationCode, ConditionType, Value, IsHandled); - if IsHandled then - exit; - TempRuleCondition.Reset(); TempRuleCondition.SetRange("Expense Category Code", CategoryCode); TempRuleCondition.SetRange("Expense Location", ExpenseLocationCode); @@ -1293,13 +1252,7 @@ codeunit 6973 "Create Expense Categories" end; internal procedure UpdateEmployeePostingGroup(Code: Code[20]; ExpenseReportPayableAccount: Code[20]; ExpensePayableBankPaidAccount: Code[20]; ExpensePayableCardPaidAccount: Code[20]; ExpenseReportPrepaymentAccount: Code[20]) - var - IsHandled: Boolean; begin - OnBeforeUpdateEmployeePostingGroup(Code, ExpenseReportPayableAccount, ExpensePayableBankPaidAccount, ExpensePayableCardPaidAccount, ExpenseReportPrepaymentAccount, IsHandled); - if IsHandled then - exit; - if not EmployeePostingGroup.Get(Code) then exit; diff --git a/src/Apps/W1/ExpenseAgent/app/src/Setup/Codeunits/CreateExpenseGLAccount.Codeunit.al b/src/Apps/W1/ExpenseAgent/app/src/Setup/Codeunits/CreateExpenseGLAccount.Codeunit.al index f9cf33b2c2a..c457823998d 100644 --- a/src/Apps/W1/ExpenseAgent/app/src/Setup/Codeunits/CreateExpenseGLAccount.Codeunit.al +++ b/src/Apps/W1/ExpenseAgent/app/src/Setup/Codeunits/CreateExpenseGLAccount.Codeunit.al @@ -50,12 +50,7 @@ codeunit 6971 "Create Expense GL Account" local procedure CreateGLAccount() var GLAccountIndent: Codeunit "G/L Account-Indent"; - IsHandled: Boolean; begin - OnBeforeCreateGLAccount(IsHandled); - if IsHandled then - exit; - InsertGLAccount(ExpenseOtherRefundableDebitAccountNo(), ExpenseOtherRefundableLbl, "G/L Account Income/Balance"::"Income Statement", Enum::"G/L Account Category"::Expense, '', Enum::"G/L Account Type"::Posting, '', '', '', 1, '', Enum::"G/L Account Type"::Posting, '', '', true, false, false); InsertGLAccount(ExpenseTravelRefundableDebitAccountNo(), ExpenseTravelRefundableLbl, "G/L Account Income/Balance"::"Income Statement", Enum::"G/L Account Category"::Expense, '', Enum::"G/L Account Type"::Posting, '', '', '', 1, '', Enum::"G/L Account Type"::Posting, '', '', true, false, false); InsertGLAccount(ExpensePerDiemRefundableDebitAccountNo(), ExpensePerDiemRefundableLbl, "G/L Account Income/Balance"::"Income Statement", Enum::"G/L Account Category"::Expense, '', Enum::"G/L Account Type"::Posting, '', '', '', 1, '', Enum::"G/L Account Type"::Posting, '', '', true, false, false); diff --git a/src/Apps/W1/ExpenseAgent/demo data/Country/AT/ATCountryData.Codeunit.al b/src/Apps/W1/ExpenseAgent/demo data/Country/AT/ATCountryData.Codeunit.al new file mode 100644 index 00000000000..1155ae8f275 --- /dev/null +++ b/src/Apps/W1/ExpenseAgent/demo data/Country/AT/ATCountryData.Codeunit.al @@ -0,0 +1,64 @@ +// ------------------------------------------------------------------------------------------------ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. See License.txt in the project root for license information. +// ------------------------------------------------------------------------------------------------ +namespace Microsoft.ExpenseAgent; + +codeunit 8323 "AT Country Data" implements "Expense Agent Country Data" +{ + Access = Internal; + InherentEntitlements = X; + InherentPermissions = X; + + procedure CreateSetupData() + var + W1CountryData: Codeunit "W1 Country Data"; + ATExpGLAccount: Codeunit "AT Exp. GL Account"; + ATExpPostingGrp: Codeunit "AT Exp. Posting Grp"; + begin + BindSubscription(ATExpGLAccount); + BindSubscription(ATExpPostingGrp); + + W1CountryData.CreateSetupData(); + Codeunit.Run(Codeunit::"AT Upd. Emp. Posting Grp"); + Codeunit.Run(Codeunit::"AT Exp. Posting Grp"); + + UnbindSubscription(ATExpPostingGrp); + UnbindSubscription(ATExpGLAccount); + end; + + procedure CreateMasterData() + var + W1CountryData: Codeunit "W1 Country Data"; + begin + W1CountryData.CreateMasterData(); + Codeunit.Run(Codeunit::"AT Exp. Categories"); + Codeunit.Run(Codeunit::"AT Exp. SubCategories"); + Codeunit.Run(Codeunit::"AT Exp. Rule Header"); + Codeunit.Run(Codeunit::"AT Exp. Rule Condition"); + end; + + procedure CreateTransactionalData() + var + W1CountryData: Codeunit "W1 Country Data"; + begin + W1CountryData.CreateTransactionalData(); + Codeunit.Run(Codeunit::"AT Expense"); + end; + + procedure CreateHistoricalData() + var + W1CountryData: Codeunit "W1 Country Data"; + ATCurrencySwapSub: Codeunit "AT Currency Swap Sub"; + ATPostedExpReport: Codeunit "AT Posted Exp. Report"; + begin + BindSubscription(ATCurrencySwapSub); + BindSubscription(ATPostedExpReport); + + W1CountryData.CreateHistoricalData(); + Codeunit.Run(Codeunit::"AT Posted Exp. Report"); + + UnbindSubscription(ATPostedExpReport); + UnbindSubscription(ATCurrencySwapSub); + end; +} diff --git a/src/Apps/W1/ExpenseAgent/demo data/Country/AT/ATCurrencySwapSub.Codeunit.al b/src/Apps/W1/ExpenseAgent/demo data/Country/AT/ATCurrencySwapSub.Codeunit.al new file mode 100644 index 00000000000..18889b92e61 --- /dev/null +++ b/src/Apps/W1/ExpenseAgent/demo data/Country/AT/ATCurrencySwapSub.Codeunit.al @@ -0,0 +1,24 @@ +// ------------------------------------------------------------------------------------------------ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. See License.txt in the project root for license information. +// ------------------------------------------------------------------------------------------------ +namespace Microsoft.ExpenseAgent; + +using Microsoft.DemoData.Finance; + +codeunit 8336 "AT Currency Swap Sub" +{ + SingleInstance = true; + EventSubscriberInstance = Manual; + InherentEntitlements = X; + InherentPermissions = X; + + [EventSubscriber(ObjectType::Codeunit, Codeunit::"Contoso Expense Agent", OnBeforeValidateCurrencyCodeInExpense, '', false, false)] + local procedure OnBeforeValidateCurrencyCodeInExpense(var CurrencyCode: Code[10]) + var + CreateCurrency: Codeunit "Create Currency"; + begin + if CurrencyCode = CreateCurrency.EUR() then + CurrencyCode := CreateCurrency.USD(); + end; +} diff --git a/src/Apps/W1/ExpenseAgent/demo data/Country/AT/ATExpCategories.Codeunit.al b/src/Apps/W1/ExpenseAgent/demo data/Country/AT/ATExpCategories.Codeunit.al new file mode 100644 index 00000000000..f4b508c2b8b --- /dev/null +++ b/src/Apps/W1/ExpenseAgent/demo data/Country/AT/ATExpCategories.Codeunit.al @@ -0,0 +1,39 @@ +// ------------------------------------------------------------------------------------------------ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. See License.txt in the project root for license information. +// ------------------------------------------------------------------------------------------------ +namespace Microsoft.ExpenseAgent; + +codeunit 8328 "AT Exp. Categories" +{ + InherentEntitlements = X; + InherentPermissions = X; + + trigger OnRun() + var + CreateExpenseGroup: Codeunit "Create Expense Group"; + CreateExpensePaymentMethod: Codeunit "Create Expense Payment Method"; + ContosoExpenseAgent: Codeunit "Contoso Expense Agent"; + ATExpPostingGrp: Codeunit "AT Exp. Posting Grp"; + begin + ContosoExpenseAgent.InsertExpenseCategory(PerDiemI(), PerDiemByAssignedPolicyLbl, PerDiemIByAssignedPolicyPostingLbl, ATExpPostingGrp.ExpensePerDiemI(), Enum::"Expense Attachment Enforcement"::" ", CreateExpensePaymentMethod.Cash(), false, false, CreateExpenseGroup.Travel(), true, Enum::"Expense Reimbursement Type"::"Employee Paid", Enum::"Expense Detail Needed"::"Per Diem"); + ContosoExpenseAgent.InsertExpenseCategory(PerDiemA(), PerDiemByAssignedPolicyLbl, PerDiemAByAssignedPolicyPostingLbl, ATExpPostingGrp.ExpensePerDiemA(), Enum::"Expense Attachment Enforcement"::" ", CreateExpensePaymentMethod.Cash(), false, false, CreateExpenseGroup.Travel(), true, Enum::"Expense Reimbursement Type"::"Employee Paid", Enum::"Expense Detail Needed"::"Per Diem"); + end; + + var + PerDiemITok: Label 'PER-DIEM-I', MaxLength = 20, Locked = true; + PerDiemATok: Label 'PER-DIEM-A', MaxLength = 20, Locked = true; + PerDiemByAssignedPolicyLbl: Label 'Expenses for per-diem or daily allowance paid for business trips, typically based on travel itinerary or other proof of travel (e.g., booking or agenda), rather than individual expense receipts.', MaxLength = 250; + PerDiemIByAssignedPolicyPostingLbl: Label 'Per-diem (international) by assigned policy', MaxLength = 100; + PerDiemAByAssignedPolicyPostingLbl: Label 'Per-diem (local) by assigned policy', MaxLength = 100; + + procedure PerDiemI(): Code[20] + begin + exit(PerDiemITok); + end; + + procedure PerDiemA(): Code[20] + begin + exit(PerDiemATok); + end; +} diff --git a/src/Apps/W1/ExpenseAgent/demo data/Country/AT/ATExpGLAccount.Codeunit.al b/src/Apps/W1/ExpenseAgent/demo data/Country/AT/ATExpGLAccount.Codeunit.al new file mode 100644 index 00000000000..e34f38ddbad --- /dev/null +++ b/src/Apps/W1/ExpenseAgent/demo data/Country/AT/ATExpGLAccount.Codeunit.al @@ -0,0 +1,57 @@ +// ------------------------------------------------------------------------------------------------ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. See License.txt in the project root for license information. +// ------------------------------------------------------------------------------------------------ +namespace Microsoft.ExpenseAgent; + +using Microsoft.DemoTool.Helpers; +using Microsoft.Finance.GeneralLedger.Account; +using Microsoft.Foundation.Enums; + +codeunit 8325 "AT Exp. GL Account" +{ + SingleInstance = true; + EventSubscriberInstance = Manual; + InherentEntitlements = X; + InherentPermissions = X; + + [EventSubscriber(ObjectType::Codeunit, Codeunit::"Create Expense G/L Account", 'OnAfterAddGLAccountsForLocalization', '', false, false)] + local procedure ModifyGLAccount() + var + GLAccountCategory: Record "G/L Account Category"; + SubCategory: Text[80]; + begin + AddGLAccounts(); + + SubCategory := Format(GLAccountCategory."Account Category"::Assets, 80); + ContosoGLAccount.InsertGLAccount(CompanyCreditCardsClearingAccount(), CompanyCreditCardsClearingAccountName(), "G/L Account Income/Balance"::"Balance Sheet", Enum::"G/L Account Category"::Assets, SubCategory, Enum::"G/L Account Type"::Posting, '', '', '', 0, '', Enum::"General Posting Type"::" ", '', '', true, false, false); + + SubCategory := Format(GLAccountCategory."Account Category"::Expense, 80); + ContosoGLAccount.InsertGLAccount(ExpenseGLAccount.MealExpensesDeductibleAccount(), ExpenseGLAccount.MealExpensesDeductibleAccountName(), "G/L Account Income/Balance"::"Income Statement", Enum::"G/L Account Category"::Expense, SubCategory, Enum::"G/L Account Type"::Posting, '', '', '', 0, '', Enum::"General Posting Type"::Purchase, '', '', true, false, false); + ContosoGLAccount.InsertGLAccount(ExpenseGLAccount.MealExpensesNondeductibleAccount(), ExpenseGLAccount.MealExpensesNondeductibleAccountName(), "G/L Account Income/Balance"::"Income Statement", Enum::"G/L Account Category"::Expense, SubCategory, Enum::"G/L Account Type"::Posting, '', '', '', 0, '', Enum::"General Posting Type"::Purchase, '', '', true, false, false); + ContosoGLAccount.InsertGLAccount(ExpenseGLAccount.MiscExternalExpensesNondeductibleAccount(), ExpenseGLAccount.MiscExternalExpensesNondeductibleAccountName(), "G/L Account Income/Balance"::"Income Statement", Enum::"G/L Account Category"::Expense, SubCategory, Enum::"G/L Account Type"::Posting, '', '', '', 0, '', Enum::"General Posting Type"::Purchase, '', '', true, false, false); + end; + + local procedure AddGLAccounts() + begin + ContosoGLAccount.AddAccountForLocalization(CompanyCreditCardsClearingAccountName(), '2830'); + ContosoGLAccount.AddAccountForLocalization(ExpenseGLAccount.MealExpensesDeductibleAccountName(), '7691'); + ContosoGLAccount.AddAccountForLocalization(ExpenseGLAccount.MealExpensesNondeductibleAccountName(), '7692'); + ContosoGLAccount.AddAccountForLocalization(ExpenseGLAccount.MiscExternalExpensesNondeductibleAccountName(), '7745'); + end; + + var + ContosoGLAccount: Codeunit "Contoso GL Account"; + ExpenseGLAccount: Codeunit "Create Expense G/L Account"; + CompanyCreditCardsClearingAccountTok: Label 'Company credit card clearing account', MaxLength = 100; + + procedure CompanyCreditCardsClearingAccount(): Code[20] + begin + exit(ContosoGLAccount.GetAccountNo(CompanyCreditCardsClearingAccountName())); + end; + + procedure CompanyCreditCardsClearingAccountName(): Text[100] + begin + exit(CompanyCreditCardsClearingAccountTok); + end; +} diff --git a/src/Apps/W1/ExpenseAgent/demo data/Country/AT/ATExpPostingGrp.Codeunit.al b/src/Apps/W1/ExpenseAgent/demo data/Country/AT/ATExpPostingGrp.Codeunit.al new file mode 100644 index 00000000000..c32604d5ef7 --- /dev/null +++ b/src/Apps/W1/ExpenseAgent/demo data/Country/AT/ATExpPostingGrp.Codeunit.al @@ -0,0 +1,76 @@ +// ------------------------------------------------------------------------------------------------ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. See License.txt in the project root for license information. +// ------------------------------------------------------------------------------------------------ +namespace Microsoft.ExpenseAgent; + +using Microsoft.DemoData.Finance; + +codeunit 8326 "AT Exp. Posting Grp" +{ + SingleInstance = true; + EventSubscriberInstance = Manual; + InherentEntitlements = X; + InherentPermissions = X; + + trigger OnRun() + var + ContosoExpenseAgent: Codeunit "Contoso Expense Agent"; + begin + ContosoExpenseAgent.InsertExpensePostingGroup(ExpensePerDiemI(), ExpensePerDiemInCountryLbl); + ContosoExpenseAgent.InsertExpensePostingGroup(ExpensePerDiemA(), ExpensePerDiemAbroadLbl); + end; + + [EventSubscriber(ObjectType::Table, Database::"Expense Posting Group", 'OnBeforeInsertEvent', '', false, false)] + local procedure OnInsertRecord(var Rec: Record "Expense Posting Group") + var + CreateGLAccount: Codeunit "Create G/L Account"; + ATGLAccountNames: Codeunit "AT GL Account Names"; + ExpenseGLAccount: Codeunit "Create Expense G/L Account"; + CreateExpensePostingGroup: Codeunit "Create Expense Posting Group"; + begin + case Rec.Code of + CreateExpensePostingGroup.ExpenseEntertainment(): + ValidateRecordFields(Rec, ExpenseGLAccount.FindGLAccountByName(ATGLAccountNames.HospitalityDomesticDeductibleAmountName()), '', ExpenseGLAccount.FindGLAccountByName(ATGLAccountNames.SettlementAccountCashBankName()), ExpenseGLAccount.FindGLAccountByName(CreateGLAccount.ApplicationRoundingName()), ExpenseGLAccount.FindGLAccountByName(CreateGLAccount.ApplicationRoundingName())); + CreateExpensePostingGroup.ExpenseMeals(): + ValidateRecordFields(Rec, ExpenseGLAccount.MealExpensesDeductibleAccount(), ExpenseGLAccount.MealExpensesNondeductibleAccount(), ExpenseGLAccount.FindGLAccountByName(ATGLAccountNames.SettlementAccountCashBankName()), ExpenseGLAccount.FindGLAccountByName(CreateGLAccount.ApplicationRoundingName()), ExpenseGLAccount.FindGLAccountByName(CreateGLAccount.ApplicationRoundingName())); + CreateExpensePostingGroup.ExpenseMileage(): + ValidateRecordFields(Rec, ExpenseGLAccount.FindGLAccountByName(ATGLAccountNames.KilometerAllowanceName()), '', ExpenseGLAccount.FindGLAccountByName(ATGLAccountNames.SettlementAccountCashBankName()), ExpenseGLAccount.FindGLAccountByName(CreateGLAccount.ApplicationRoundingName()), ExpenseGLAccount.FindGLAccountByName(CreateGLAccount.ApplicationRoundingName())); + CreateExpensePostingGroup.ExpenseOther(): + ValidateRecordFields(Rec, ExpenseGLAccount.FindGLAccountByName(ATGLAccountNames.OtherName()), ExpenseGLAccount.MiscExternalExpensesNondeductibleAccount(), ExpenseGLAccount.FindGLAccountByName(ATGLAccountNames.SettlementAccountCashBankName()), ExpenseGLAccount.FindGLAccountByName(CreateGLAccount.ApplicationRoundingName()), ExpenseGLAccount.FindGLAccountByName(CreateGLAccount.ApplicationRoundingName())); + ExpensePerDiemI(): + ValidateRecordFields(Rec, ExpenseGLAccount.FindGLAccountByName(ATGLAccountNames.MealExpensesDomesticName()), '', ExpenseGLAccount.FindGLAccountByName(ATGLAccountNames.SettlementAccountCashBankName()), ExpenseGLAccount.FindGLAccountByName(CreateGLAccount.ApplicationRoundingName()), ExpenseGLAccount.FindGLAccountByName(CreateGLAccount.ApplicationRoundingName())); + ExpensePerDiemA(): + ValidateRecordFields(Rec, ExpenseGLAccount.FindGLAccountByName(ATGLAccountNames.MealExpensesAbroadName()), '', ExpenseGLAccount.FindGLAccountByName(ATGLAccountNames.SettlementAccountCashBankName()), ExpenseGLAccount.FindGLAccountByName(CreateGLAccount.ApplicationRoundingName()), ExpenseGLAccount.FindGLAccountByName(CreateGLAccount.ApplicationRoundingName())); + CreateExpensePostingGroup.ExpenseTravel(): + ValidateRecordFields(Rec, ExpenseGLAccount.FindGLAccountByName(ATGLAccountNames.TransportationThirdPartiesName()), ExpenseGLAccount.MiscExternalExpensesNondeductibleAccount(), ExpenseGLAccount.FindGLAccountByName(ATGLAccountNames.SettlementAccountCashBankName()), ExpenseGLAccount.FindGLAccountByName(CreateGLAccount.ApplicationRoundingName()), ExpenseGLAccount.FindGLAccountByName(CreateGLAccount.ApplicationRoundingName())); + CreateExpensePostingGroup.ExpenseRentalCars(): + ValidateRecordFields(Rec, ExpenseGLAccount.FindGLAccountByName(ATGLAccountNames.TransportationThirdPartiesName()), '', ExpenseGLAccount.FindGLAccountByName(ATGLAccountNames.SettlementAccountCashBankName()), ExpenseGLAccount.FindGLAccountByName(CreateGLAccount.ApplicationRoundingName()), ExpenseGLAccount.FindGLAccountByName(CreateGLAccount.ApplicationRoundingName())); + end; + end; + + local procedure ValidateRecordFields(var ExpensePostingGroup: Record "Expense Posting Group"; RefundableDebitAccount: Code[20]; NonRefundableDebitAccount: Code[20]; PrepaymentCreditAccount: Code[20]; ExpenseDebitRoundingAccount: Code[20]; ExpenseCreditRoundingAccount: Code[20]) + begin + ExpensePostingGroup.Validate("Refundable Debit Account", RefundableDebitAccount); + ExpensePostingGroup.Validate("Non-Refundable Debit Account", NonRefundableDebitAccount); + ExpensePostingGroup.Validate("Prepayment Credit Account", PrepaymentCreditAccount); + ExpensePostingGroup.Validate("Debit Rounding Account", ExpenseDebitRoundingAccount); + ExpensePostingGroup.Validate("Credit Rounding Account", ExpenseCreditRoundingAccount); + end; + + var + ExpensePERDIEMITok: Label 'EXPENSE-PERDIEM-I', MaxLength = 20, Locked = true; + ExpensePerDiemInCountryLbl: Label 'Expense - Per Diem in country', MaxLength = 100; + ExpensePERDIEMATok: Label 'EXPENSE-PERDIEM-A', MaxLength = 20, Locked = true; + ExpensePerDiemAbroadLbl: Label 'Expense - Per Diem abroad', MaxLength = 100; + + procedure ExpensePerDiemI(): Code[20] + begin + exit(ExpensePERDIEMITok); + end; + + procedure ExpensePerDiemA(): Code[20] + begin + exit(ExpensePERDIEMATok); + end; +} diff --git a/src/Apps/W1/ExpenseAgent/demo data/Country/AT/ATExpRuleCondition.Codeunit.al b/src/Apps/W1/ExpenseAgent/demo data/Country/AT/ATExpRuleCondition.Codeunit.al new file mode 100644 index 00000000000..84496f32359 --- /dev/null +++ b/src/Apps/W1/ExpenseAgent/demo data/Country/AT/ATExpRuleCondition.Codeunit.al @@ -0,0 +1,26 @@ +// ------------------------------------------------------------------------------------------------ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. See License.txt in the project root for license information. +// ------------------------------------------------------------------------------------------------ +namespace Microsoft.ExpenseAgent; + +codeunit 8331 "AT Exp. Rule Condition" +{ + InherentEntitlements = X; + InherentPermissions = X; + + trigger OnRun() + var + ATExpCategories: Codeunit "AT Exp. Categories"; + CreateExpenseLocation: Codeunit "Create Expense Location"; + ContosoExpenseAgent: Codeunit "Contoso Expense Agent"; + begin + ContosoExpenseAgent.InsertExpenseRuleCondition(ATExpCategories.PerDiemI(), CreateExpenseLocation.CanadaAll(), 0D, 10000, Enum::"Expense Rule Condition Type"::"Daily Rate", 125); + ContosoExpenseAgent.InsertExpenseRuleCondition(ATExpCategories.PerDiemI(), CreateExpenseLocation.DenmarkAll(), 0D, 10000, Enum::"Expense Rule Condition Type"::"Daily Rate", 450); + ContosoExpenseAgent.InsertExpenseRuleCondition(ATExpCategories.PerDiemA(), CreateExpenseLocation.Domestic(), 0D, 10000, Enum::"Expense Rule Condition Type"::"Daily Rate", 50); + ContosoExpenseAgent.InsertExpenseRuleCondition(ATExpCategories.PerDiemI(), CreateExpenseLocation.FranceAll(), 0D, 10000, Enum::"Expense Rule Condition Type"::"Daily Rate", 110); + ContosoExpenseAgent.InsertExpenseRuleCondition(ATExpCategories.PerDiemI(), CreateExpenseLocation.GermanyAll(), 0D, 10000, Enum::"Expense Rule Condition Type"::"Daily Rate", 105); + ContosoExpenseAgent.InsertExpenseRuleCondition(ATExpCategories.PerDiemI(), CreateExpenseLocation.UKOther(), 0D, 10000, Enum::"Expense Rule Condition Type"::"Daily Rate", 115); + ContosoExpenseAgent.InsertExpenseRuleCondition(ATExpCategories.PerDiemI(), CreateExpenseLocation.USAOther(), 0D, 10000, Enum::"Expense Rule Condition Type"::"Daily Rate", 120); + end; +} diff --git a/src/Apps/W1/ExpenseAgent/demo data/Country/AT/ATExpRuleHeader.Codeunit.al b/src/Apps/W1/ExpenseAgent/demo data/Country/AT/ATExpRuleHeader.Codeunit.al new file mode 100644 index 00000000000..09dfcbe87d7 --- /dev/null +++ b/src/Apps/W1/ExpenseAgent/demo data/Country/AT/ATExpRuleHeader.Codeunit.al @@ -0,0 +1,29 @@ +// ------------------------------------------------------------------------------------------------ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. See License.txt in the project root for license information. +// ------------------------------------------------------------------------------------------------ +namespace Microsoft.ExpenseAgent; + +using Microsoft.DemoData.Finance; + +codeunit 8330 "AT Exp. Rule Header" +{ + InherentEntitlements = X; + InherentPermissions = X; + + trigger OnRun() + var + CreateCurrency: Codeunit "Create Currency"; + ATExpCategories: Codeunit "AT Exp. Categories"; + CreateExpenseLocation: Codeunit "Create Expense Location"; + ContosoExpenseAgent: Codeunit "Contoso Expense Agent"; + begin + ContosoExpenseAgent.InsertExpenseRuleHeader(ATExpCategories.PerDiemI(), CreateExpenseLocation.CanadaAll(), 0D, Enum::"Expense Justification"::" ", false, '', CreateCurrency.CAD(), ''); + ContosoExpenseAgent.InsertExpenseRuleHeader(ATExpCategories.PerDiemI(), CreateExpenseLocation.DenmarkAll(), 0D, Enum::"Expense Justification"::" ", false, '', CreateCurrency.USD(), ''); + ContosoExpenseAgent.InsertExpenseRuleHeader(ATExpCategories.PerDiemA(), CreateExpenseLocation.Domestic(), 0D, Enum::"Expense Justification"::" ", false, '', '', ''); + ContosoExpenseAgent.InsertExpenseRuleHeader(ATExpCategories.PerDiemI(), CreateExpenseLocation.FranceAll(), 0D, Enum::"Expense Justification"::" ", false, '', CreateCurrency.USD(), ''); + ContosoExpenseAgent.InsertExpenseRuleHeader(ATExpCategories.PerDiemI(), CreateExpenseLocation.GermanyAll(), 0D, Enum::"Expense Justification"::" ", false, '', CreateCurrency.USD(), ''); + ContosoExpenseAgent.InsertExpenseRuleHeader(ATExpCategories.PerDiemI(), CreateExpenseLocation.UKOther(), 0D, Enum::"Expense Justification"::" ", false, '', CreateCurrency.GBP(), ''); + ContosoExpenseAgent.InsertExpenseRuleHeader(ATExpCategories.PerDiemI(), CreateExpenseLocation.USAOther(), 0D, Enum::"Expense Justification"::" ", false, '', CreateCurrency.USD(), ''); + end; +} diff --git a/src/Apps/W1/ExpenseAgent/demo data/Country/AT/ATExpSubCategories.Codeunit.al b/src/Apps/W1/ExpenseAgent/demo data/Country/AT/ATExpSubCategories.Codeunit.al new file mode 100644 index 00000000000..5217ff5c5a4 --- /dev/null +++ b/src/Apps/W1/ExpenseAgent/demo data/Country/AT/ATExpSubCategories.Codeunit.al @@ -0,0 +1,39 @@ +// ------------------------------------------------------------------------------------------------ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. See License.txt in the project root for license information. +// ------------------------------------------------------------------------------------------------ +namespace Microsoft.ExpenseAgent; + +codeunit 8329 "AT Exp. SubCategories" +{ + InherentEntitlements = X; + InherentPermissions = X; + + trigger OnRun() + var + ContosoExpenseAgent: Codeunit "Contoso Expense Agent"; + ATExpCategories: Codeunit "AT Exp. Categories"; + begin + // PER-DIEM subcategories + ContosoExpenseAgent.InsertExpenseSubcategory(Country(), ATExpCategories.PerDiemA(), LocalCountryPerDiemLbl, LocalCountryPerDiemPostingLbl, false, true, false); + ContosoExpenseAgent.InsertExpenseSubcategory(Intl(), ATExpCategories.PerDiemI(), InternationalPerDiemLbl, InternationalPerDiemPostingLbl, false, true, false); + end; + + var + CountryTok: Label 'COUNTRY', MaxLength = 20, Locked = true; + IntlTok: Label 'INTL', MaxLength = 20, Locked = true; + LocalCountryPerDiemLbl: Label 'Daily per-diem allowance based on domestic travel rates, paid instead of individual meal or incidental expense reimbursements.', MaxLength = 250; + InternationalPerDiemLbl: Label 'Daily per-diem allowance for international business travel, based on applicable foreign travel rates.', MaxLength = 250; + LocalCountryPerDiemPostingLbl: Label 'Local country per-diem', MaxLength = 100; + InternationalPerDiemPostingLbl: Label 'International per-diem', MaxLength = 100; + + procedure Country(): Code[20] + begin + exit(CountryTok); + end; + + procedure Intl(): Code[20] + begin + exit(IntlTok); + end; +} diff --git a/src/Apps/W1/ExpenseAgent/demo data/Country/AT/ATExpense.Codeunit.al b/src/Apps/W1/ExpenseAgent/demo data/Country/AT/ATExpense.Codeunit.al new file mode 100644 index 00000000000..449b8feaf69 --- /dev/null +++ b/src/Apps/W1/ExpenseAgent/demo data/Country/AT/ATExpense.Codeunit.al @@ -0,0 +1,51 @@ +// ------------------------------------------------------------------------------------------------ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. See License.txt in the project root for license information. +// ------------------------------------------------------------------------------------------------ +namespace Microsoft.ExpenseAgent; + +using Microsoft.DemoTool.Helpers; + +codeunit 8332 "AT Expense" +{ + InherentEntitlements = X; + InherentPermissions = X; + Permissions = tabledata "Expense Per Diem" = rim; + + trigger OnRun() + begin + CreateOpenExpense(); + end; + + local procedure CreateOpenExpense() + var + Expense: Record Expense; + ContosoExpenseAgent: Codeunit "Contoso Expense Agent"; + CreateExpenseLocation: Codeunit "Create Expense Location"; + begin + Expense := ContosoExpenseAgent.InsertExpense(CreateExpenseUser.EH(), ATExpCategories.PerDiemI(), CreateExpenseLocation.FranceAll(), PerDiemByAssignedPolicyLbl, '', ContosoUtility.AdjustDate(19030203D), '', 0, '', CreateExpensePaymentMethod.Cash(), true, false, '', CreateDateTime(ContosoUtility.AdjustDate(19030115D), 144000T), CreateDateTime(ContosoUtility.AdjustDate(19030121D), 000500T), 0, 0, '', '', '', '', ''); + UpdateExpensePerDiem(Expense."No.", 10000, false, false, true); + UpdateExpensePerDiem(Expense."No.", 30000, false, true, false); + UpdateExpensePerDiem(Expense."No.", 40000, false, false, true); + UpdateExpensePerDiem(Expense."No.", 60000, false, true, true); + end; + + var + ContosoUtility: Codeunit "Contoso Utilities"; + CreateExpenseUser: Codeunit "Create Expense User"; + ATExpCategories: Codeunit "AT Exp. Categories"; + CreateExpensePaymentMethod: Codeunit "Create Expense Payment Method"; + PerDiemByAssignedPolicyLbl: Label 'Per-diem by assigned policy', MaxLength = 100; + + local procedure UpdateExpensePerDiem(ExpenseNo: Code[20]; LineNo: Integer; Breakfast: Boolean; Lunch: Boolean; Dinner: Boolean) + var + ExpensePerDiem: Record "Expense Per Diem"; + begin + ExpensePerDiem.Get(ExpenseNo, LineNo); + + ExpensePerDiem.Validate(Breakfast, Breakfast); + ExpensePerDiem.Validate(Lunch, Lunch); + ExpensePerDiem.Validate(Dinner, Dinner); + ExpensePerDiem.Modify(); + end; +} diff --git a/src/Apps/W1/ExpenseAgent/demo data/Country/AT/ATGLAccountNames.Codeunit.al b/src/Apps/W1/ExpenseAgent/demo data/Country/AT/ATGLAccountNames.Codeunit.al new file mode 100644 index 00000000000..75baf158068 --- /dev/null +++ b/src/Apps/W1/ExpenseAgent/demo data/Country/AT/ATGLAccountNames.Codeunit.al @@ -0,0 +1,62 @@ +// ------------------------------------------------------------------------------------------------ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. See License.txt in the project root for license information. +// ------------------------------------------------------------------------------------------------ +namespace Microsoft.ExpenseAgent; + +codeunit 8324 "AT GL Account Names" +{ + Access = Internal; + InherentEntitlements = X; + InherentPermissions = X; + + var + SettlementAccountCashBankTok: Label 'Settlement account cash bank', MaxLength = 100; + SalesRevenuesResourcesExportTok: Label 'Sales revenues resources export', MaxLength = 100; + TransportationThirdPartiesTok: Label 'Transportation third parties', MaxLength = 100; + KilometerAllowanceTok: Label 'Kilometer allowance', MaxLength = 100; + MealExpensesDomesticTok: Label 'Meal expenses domestic', MaxLength = 100; + MealExpensesAbroadTok: Label 'Meal expenses abroad', MaxLength = 100; + HospitalityDomesticDeductibleAmountTok: Label 'Hospitality domestic deductible amount', MaxLength = 100; + OtherTok: Label 'Other', MaxLength = 100; + + procedure SettlementAccountCashBankName(): Text[100] + begin + exit(SettlementAccountCashBankTok); + end; + + procedure SalesRevenuesResourcesExportName(): Text[100] + begin + exit(SalesRevenuesResourcesExportTok); + end; + + procedure TransportationThirdPartiesName(): Text[100] + begin + exit(TransportationThirdPartiesTok); + end; + + procedure KilometerAllowanceName(): Text[100] + begin + exit(KilometerAllowanceTok); + end; + + procedure MealExpensesDomesticName(): Text[100] + begin + exit(MealExpensesDomesticTok); + end; + + procedure MealExpensesAbroadName(): Text[100] + begin + exit(MealExpensesAbroadTok); + end; + + procedure HospitalityDomesticDeductibleAmountName(): Text[100] + begin + exit(HospitalityDomesticDeductibleAmountTok); + end; + + procedure OtherName(): Text[100] + begin + exit(OtherTok); + end; +} diff --git a/src/Apps/W1/ExpenseAgent/demo data/Country/AT/ATPostedExpReport.Codeunit.al b/src/Apps/W1/ExpenseAgent/demo data/Country/AT/ATPostedExpReport.Codeunit.al new file mode 100644 index 00000000000..d85e3e23b3b --- /dev/null +++ b/src/Apps/W1/ExpenseAgent/demo data/Country/AT/ATPostedExpReport.Codeunit.al @@ -0,0 +1,168 @@ +// ------------------------------------------------------------------------------------------------ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. See License.txt in the project root for license information. +// ------------------------------------------------------------------------------------------------ +namespace Microsoft.ExpenseAgent; + +using Microsoft.DemoData.Finance; +using Microsoft.DemoData.HumanResources; +using Microsoft.DemoTool.Helpers; + +codeunit 8335 "AT Posted Exp. Report" +{ + SingleInstance = true; + EventSubscriberInstance = Manual; + InherentEntitlements = X; + InherentPermissions = X; + Permissions = + tabledata "Expense Per Diem" = rim, + tabledata "Expense Report Line" = rim; + + trigger OnRun() + var + ExpenseReportHeader: Record "Expense Report Header"; + begin + if ExpenseReportHeader.FindLast() then + FromExpenseReportNo := ExpenseReportHeader."No."; + + CreateExpenseReportToPost(); + + PostExpenseReport(); + end; + + [EventSubscriber(ObjectType::Codeunit, Codeunit::"Create Posted Expense Report", OnDefineExpenseAccountNo, '', false, false)] + local procedure OnDefineExpenseAccountNo(var AccountNo: Code[20]) + var + ATGLAccountNames: Codeunit "AT GL Account Names"; + ExpenseGLAccount: Codeunit "Create Expense G/L Account"; + begin + AccountNo := ExpenseGLAccount.FindGLAccountByName(ATGLAccountNames.SalesRevenuesResourcesExportName()); + end; + + local procedure CreateExpenseReportToPost() + var + Expense: Record Expense; + ExpenseReportHeader: Record "Expense Report Header"; + CreateEmployee: Codeunit "Create Employee"; + CreateCurrency: Codeunit "Create Currency"; + ContosoUtility: Codeunit "Contoso Utilities"; + CreateExpenseUser: Codeunit "Create Expense User"; + CreateExpenseLocation: Codeunit "Create Expense Location"; + ContosoExpenseAgent: Codeunit "Contoso Expense Agent"; + CreateExpCategories: Codeunit "Create Expense Categories DM"; + ATExpCategories: Codeunit "AT Exp. Categories"; + CreateExpenseSubcategories: Codeunit "Create Expense Subcategories"; + CreateExpensePaymentMethod: Codeunit "Create Expense Payment Method"; + begin + ExpenseReportHeader := ContosoExpenseAgent.InsertExpenseReportHeader(CreateExpenseUser.JO(), ContosoUtility.AdjustDate(19021104D), ContosoUtility.AdjustDate(19021104D)); + Expense := ContosoExpenseAgent.InsertExpense(CreateExpenseUser.JO(), ATExpCategories.PerDiemI(), CreateExpenseLocation.GermanyAll(), BusinessTripToHamburgLbl, '', ContosoUtility.AdjustDate(19021103D), '', 0, '', CreateExpensePaymentMethod.Cash(), true, false, '', CreateDateTime(ContosoUtility.AdjustDate(19021024D), 064500T), CreateDateTime(ContosoUtility.AdjustDate(19021027D), 161500T), 0, 0, '', '', '', '', ''); + ReleaseAndAddExpenseToExpenseReport(Expense, ExpenseReportHeader); + Expense := ContosoExpenseAgent.InsertExpense(CreateExpenseUser.JO(), CreateExpCategories.Airline(), '', AirlineTicketsLbl, '', ContosoUtility.AdjustDate(19021010D), '', 2042, MargieTravelLbl, CreateExpensePaymentMethod.Card(), true, false, '', 0DT, 0DT, 0, 0, '', '', 'TY6HJO', '', ''); + ReleaseAndAddExpenseToExpenseReport(Expense, ExpenseReportHeader); + + ExpenseReportHeader := ContosoExpenseAgent.InsertExpenseReportHeader(CreateExpenseUser.EH(), ContosoUtility.AdjustDate(19021204D), ContosoUtility.AdjustDate(19021204D)); + Expense := ContosoExpenseAgent.InsertExpense(CreateExpenseUser.EH(), CreateExpCategories.Airline(), '', AirlineTicketsDublinLbl, TravelToConferenceLbl, ContosoUtility.AdjustDate(19021106D), '', 3120, MargieTravelLbl, CreateExpensePaymentMethod.Card(), true, false, '', 0DT, 0DT, 0, 0, '', '', 'FIUXHJT', '', ''); + ReleaseAndAddExpenseToExpenseReport(Expense, ExpenseReportHeader); + Expense := ContosoExpenseAgent.InsertExpense(CreateExpenseUser.EH(), CreateExpCategories.Events(), '', ITConferenceLbl, '', ContosoUtility.AdjustDate(19021107D), CreateCurrency.EUR(), 1990, ProsewareIncLbl, CreateExpensePaymentMethod.Card(), true, false, '', 0DT, 0DT, 0, 0, '', '', 'G574576HJ656', '', ''); + ReleaseAndAddExpenseToExpenseReport(Expense, ExpenseReportHeader); + Expense := ContosoExpenseAgent.InsertExpense(CreateExpenseUser.EH(), CreateExpCategories.GroundTransportation(), '', TaxiLbl, '', ContosoUtility.AdjustDate(19021114D), CreateCurrency.EUR(), 45, TailwindTradersLbl, CreateExpensePaymentMethod.Cash(), true, false, '', 0DT, 0DT, 0, 0, '', '', '456845856867', '', ''); + ReleaseAndAddExpenseToExpenseReport(Expense, ExpenseReportHeader); + Expense := ContosoExpenseAgent.InsertExpense(CreateExpenseUser.EH(), CreateExpCategories.Entertain(), '', BusinessDinnerLbl, BusinessDinnerWithBigPotentialCustomersLbl, ContosoUtility.AdjustDate(19021116D), CreateCurrency.EUR(), 842, FourthCoffeeLbl, CreateExpensePaymentMethod.Card(), true, false, '', 0DT, 0DT, 0, 0, '', '', 'RT6457560034', '', ''); + ContosoExpenseAgent.InsertExpenseParticipant(Expense."No.", 10000, CreateExpCategories.Entertain(), Enum::"Expense Participant Type"::Employee, CreateEmployee.ManagingDirector(), '', '', '', '', ''); + ContosoExpenseAgent.InsertExpenseParticipant(Expense."No.", 20000, CreateExpCategories.Entertain(), Enum::"Expense Participant Type"::Employee, CreateEmployee.SalesManager(), '', '', '', '', ''); + ContosoExpenseAgent.InsertExpenseParticipant(Expense."No.", 30000, CreateExpCategories.Entertain(), Enum::"Expense Participant Type"::External, '', JesseHomerLbl, RelecloudLbl, '', CEOLbl, 'jesse.homer@contoso.com'); + ContosoExpenseAgent.InsertExpenseParticipant(Expense."No.", 40000, CreateExpCategories.Entertain(), Enum::"Expense Participant Type"::External, '', RobertTownesLbl, AdatumCorporationLbl, '', CEOLbl, 'robert.townes@contoso.com'); + ReleaseAndAddExpenseToExpenseReport(Expense, ExpenseReportHeader); + Expense := ContosoExpenseAgent.InsertExpense(CreateExpenseUser.EH(), CreateExpCategories.Hotels(), '', HotelStayLbl, '', ContosoUtility.AdjustDate(19021118D), CreateCurrency.EUR(), 2150, ContosoSuitesLbl, CreateExpensePaymentMethod.Card(), true, false, '', 0DT, 0DT, 0, 0, '', '', '64675S879CT987990004', '', ''); + ContosoExpenseAgent.InsertExpenseItemization(Expense."No.", 10000, CreateExpCategories.Hotels(), CreateExpenseSubcategories.Room(), AccommodationLbl, ContosoUtility.AdjustDate(19021114D), 390); + ContosoExpenseAgent.InsertExpenseItemization(Expense."No.", 20000, CreateExpCategories.Hotels(), CreateExpenseSubcategories.Breakfast(), BreakfastLbl, ContosoUtility.AdjustDate(19021115D), 35); + ContosoExpenseAgent.InsertExpenseItemization(Expense."No.", 30000, CreateExpCategories.Hotels(), CreateExpenseSubcategories.Room(), AccommodationLbl, ContosoUtility.AdjustDate(19021115D), 390); + ContosoExpenseAgent.InsertExpenseItemization(Expense."No.", 40000, CreateExpCategories.Hotels(), CreateExpenseSubcategories.Breakfast(), BreakfastLbl, ContosoUtility.AdjustDate(19021116D), 35); + ContosoExpenseAgent.InsertExpenseItemization(Expense."No.", 50000, CreateExpCategories.Hotels(), CreateExpenseSubcategories.Room(), AccommodationLbl, ContosoUtility.AdjustDate(19021116D), 390); + ContosoExpenseAgent.InsertExpenseItemization(Expense."No.", 60000, CreateExpCategories.Hotels(), CreateExpenseSubcategories.RoomService(), RoomServiceLbl, ContosoUtility.AdjustDate(19021116D), 145); + ContosoExpenseAgent.InsertExpenseItemization(Expense."No.", 70000, CreateExpCategories.Hotels(), CreateExpenseSubcategories.Breakfast(), BreakfastLbl, ContosoUtility.AdjustDate(19021117D), 35); + ContosoExpenseAgent.InsertExpenseItemization(Expense."No.", 80000, CreateExpCategories.Hotels(), CreateExpenseSubcategories.Room(), AccommodationLbl, ContosoUtility.AdjustDate(19021117D), 390); + ContosoExpenseAgent.InsertExpenseItemization(Expense."No.", 90000, CreateExpCategories.Hotels(), CreateExpenseSubcategories.Breakfast(), BreakfastLbl, ContosoUtility.AdjustDate(19021118D), 35); + ContosoExpenseAgent.InsertExpenseItemization(Expense."No.", 100000, CreateExpCategories.Hotels(), CreateExpenseSubcategories.Tax(), HotelTaxesLbl, ContosoUtility.AdjustDate(19021118D), 305); + ReleaseAndAddExpenseToExpenseReport(Expense, ExpenseReportHeader); + Expense := ContosoExpenseAgent.InsertExpense(CreateExpenseUser.EH(), CreateExpCategories.RentalCars(), '', CarRentalsLbl, '', ContosoUtility.AdjustDate(19021118D), CreateCurrency.EUR(), 622.45, VanArsdelLtdLbl, CreateExpensePaymentMethod.Card(), true, false, '', 0DT, 0DT, 0, 0, '', '', 'H6584769867J9J95789', '', ''); + ReleaseAndAddExpenseToExpenseReport(Expense, ExpenseReportHeader); + Expense := ContosoExpenseAgent.InsertExpense(CreateExpenseUser.EH(), CreateExpCategories.GroundTransportation(), '', TaxiLbl, '', ContosoUtility.AdjustDate(19021118D), CreateCurrency.EUR(), 71, TailwindTradersLbl, CreateExpensePaymentMethod.Cash(), true, false, '', 0DT, 0DT, 0, 0, '', '', '7456875687568', '', ''); + ReleaseAndAddExpenseToExpenseReport(Expense, ExpenseReportHeader); + Expense := ContosoExpenseAgent.InsertExpense(CreateExpenseUser.EH(), ATExpCategories.PerDiemI(), CreateExpenseLocation.UKOther(), TripToUKLbl, '', ContosoUtility.AdjustDate(19021121D), '', 0, '', CreateExpensePaymentMethod.Cash(), true, false, '', CreateDateTime(ContosoUtility.AdjustDate(19021114D), 053000T), CreateDateTime(ContosoUtility.AdjustDate(19021118D), 220500T), 0, 0, '', '', '', '', ''); + UpdateExpensePerDiem(Expense."No.", 20000, false, false, true); + UpdateExpensePerDiem(Expense."No.", 40000, false, true, false); + ReleaseAndAddExpenseToExpenseReport(Expense, ExpenseReportHeader); + Expense := ContosoExpenseAgent.InsertExpense(CreateExpenseUser.EH(), ATExpCategories.PerDiemA(), CreateExpenseLocation.Domestic(), TripToDoverLbl, '', ContosoUtility.AdjustDate(19021204D), '', 0, '', CreateExpensePaymentMethod.Cash(), true, false, '', CreateDateTime(ContosoUtility.AdjustDate(19021127D), 070000T), CreateDateTime(ContosoUtility.AdjustDate(19021129D), 145500T), 0, 0, '', '', '', '', ''); + ReleaseAndAddExpenseToExpenseReport(Expense, ExpenseReportHeader); + Expense := ContosoExpenseAgent.InsertExpense(CreateExpenseUser.EH(), CreateExpCategories.Mileage(), '', MileageLbl, '', ContosoUtility.AdjustDate(19031101D), '', 0, VanArsdelLtdLbl, CreateExpensePaymentMethod.Cash(), true, false, '', 0DT, 0DT, 0, 249, 'New York', 'Dover', 'H6584769867J9J95789', '', ''); + ReleaseAndAddExpenseToExpenseReport(Expense, ExpenseReportHeader); + end; + + var + FromExpenseReportNo: Code[20]; + BusinessTripToHamburgLbl: Label 'Business trip to Hamburg, DE', MaxLength = 100; + AirlineTicketsLbl: Label 'Airline tickets NY/FRANKFURT/HAMBURG/FRANKFURT/NY', MaxLength = 100; + MargieTravelLbl: Label 'Margie''s Travel', MaxLength = 100; + AirlineTicketsDublinLbl: Label 'Airline tickets NY/DUBLIN/NY', MaxLength = 100; + TravelToConferenceLbl: Label 'Travel to the conference', MaxLength = 100; + ITConferenceLbl: Label 'IT Conference', MaxLength = 100; + ProsewareIncLbl: Label 'Proseware, Inc.', MaxLength = 100; + TaxiLbl: Label 'Taxi', MaxLength = 100; + TailwindTradersLbl: Label 'Tailwind Traders', MaxLength = 100; + BusinessDinnerLbl: Label 'Business Dinner', MaxLength = 100; + BusinessDinnerWithBigPotentialCustomersLbl: Label 'Business dinner with a big potential customers', MaxLength = 100; + FourthCoffeeLbl: Label 'Fourth Coffee', MaxLength = 100; + JesseHomerLbl: Label 'Jesse Homer', MaxLength = 100; + RelecloudLbl: Label 'Relecloud', MaxLength = 100; + RobertTownesLbl: Label 'Robert Townes', MaxLength = 100; + AdatumCorporationLbl: Label 'Adatum Corporation', MaxLength = 100; + HotelStayLbl: Label 'Hotel stay', MaxLength = 100; + ContosoSuitesLbl: Label 'Contoso Suites', MaxLength = 100; + AccommodationLbl: Label 'Accommodation', MaxLength = 100; + BreakfastLbl: Label 'Breakfast', MaxLength = 100; + HotelTaxesLbl: Label 'Hotel Taxes', MaxLength = 100; + RoomServiceLbl: Label 'Room service', MaxLength = 100; + CarRentalsLbl: Label 'Car Rentals', MaxLength = 100; + VanArsdelLtdLbl: Label 'VanArsdel, Ltd.', MaxLength = 100; + TripToUKLbl: Label 'Trip to UK', MaxLength = 100; + TripToDoverLbl: Label 'Trip to Dover', MaxLength = 100; + MileageLbl: Label 'Mileage', MaxLength = 100; + CEOLbl: Label 'CEO', MaxLength = 30; + + local procedure ReleaseAndAddExpenseToExpenseReport(Expense: Record Expense; ExpenseReportHeader: Record "Expense Report Header") + var + ReleaseExpenseDocument: Codeunit "Release Expense Document"; + CreateExpenseReport: Codeunit "Create Expense Report"; + begin + Expense.Get(Expense."No."); + ReleaseExpenseDocument.Run(Expense); + + CreateExpenseReport.AddSingleExpenseToExpenseReport(Expense, ExpenseReportHeader); + end; + + local procedure PostExpenseReport() + var + ExpenseReportHeader: Record "Expense Report Header"; + begin + if FromExpenseReportNo <> '' then + ExpenseReportHeader.SetFilter("No.", '>%1', FromExpenseReportNo); + + if ExpenseReportHeader.FindSet() then + repeat + Codeunit.Run(Codeunit::"Expense Report-Post", ExpenseReportHeader); + until ExpenseReportHeader.Next() = 0; + end; + + local procedure UpdateExpensePerDiem(ExpenseNo: Code[20]; LineNo: Integer; Breakfast: Boolean; Lunch: Boolean; Dinner: Boolean) + var + ExpensePerDiem: Record "Expense Per Diem"; + begin + ExpensePerDiem.Get(ExpenseNo, LineNo); + + ExpensePerDiem.Validate(Breakfast, Breakfast); + ExpensePerDiem.Validate(Lunch, Lunch); + ExpensePerDiem.Validate(Dinner, Dinner); + ExpensePerDiem.Modify(); + end; +} diff --git a/src/Apps/W1/ExpenseAgent/demo data/Country/AT/ATUpdEmpPostingGrp.Codeunit.al b/src/Apps/W1/ExpenseAgent/demo data/Country/AT/ATUpdEmpPostingGrp.Codeunit.al new file mode 100644 index 00000000000..02d880a92dd --- /dev/null +++ b/src/Apps/W1/ExpenseAgent/demo data/Country/AT/ATUpdEmpPostingGrp.Codeunit.al @@ -0,0 +1,34 @@ +// ------------------------------------------------------------------------------------------------ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. See License.txt in the project root for license information. +// ------------------------------------------------------------------------------------------------ +namespace Microsoft.ExpenseAgent; + +using Microsoft.DemoData.Finance; +using Microsoft.DemoData.HumanResources; + +codeunit 8327 "AT Upd. Emp. Posting Grp" +{ + InherentEntitlements = X; + InherentPermissions = X; + + trigger OnRun() + begin + UpdateEmployeePostingGroup(); + end; + + local procedure UpdateEmployeePostingGroup() + var + CreateGLAccount: Codeunit "Create G/L Account"; + HRGLAccount: Codeunit "Create HR GL Account"; + ExpenseGLAccount: Codeunit "Create Expense G/L Account"; + ATExpGLAccount: Codeunit "AT Exp. GL Account"; + ATGLAccountNames: Codeunit "AT GL Account Names"; + ContosoExpenseAgent: Codeunit "Contoso Expense Agent"; + CreateEmployeePostingGroup: Codeunit "Create Employee Posting Group"; + begin + ContosoExpenseAgent.SetOverwriteData(true); + ContosoExpenseAgent.UpdateEmployeePostingGroup(CreateEmployeePostingGroup.EmployeeExpenses(), ExpenseGLAccount.FindGLAccountByName(HRGLAccount.EmployeesPayableName()), ExpenseGLAccount.FindGLAccountByName(ATGLAccountNames.SettlementAccountCashBankName()), ExpenseGLAccount.FindGLAccountByName(CreateGLAccount.BankLcyName()), ATExpGLAccount.CompanyCreditCardsClearingAccount()); + ContosoExpenseAgent.SetOverwriteData(false); + end; +} diff --git a/src/Apps/W1/ExpenseAgent/demo data/Country/AU/AUCountryData.Codeunit.al b/src/Apps/W1/ExpenseAgent/demo data/Country/AU/AUCountryData.Codeunit.al new file mode 100644 index 00000000000..6be231090ed --- /dev/null +++ b/src/Apps/W1/ExpenseAgent/demo data/Country/AU/AUCountryData.Codeunit.al @@ -0,0 +1,61 @@ +// ------------------------------------------------------------------------------------------------ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. See License.txt in the project root for license information. +// ------------------------------------------------------------------------------------------------ +namespace Microsoft.ExpenseAgent; + +codeunit 8265 "AU Country Data" implements "Expense Agent Country Data" +{ + Access = Internal; + InherentEntitlements = X; + InherentPermissions = X; + + procedure CreateSetupData() + var + W1CountryData: Codeunit "W1 Country Data"; + AUExpGLAccount: Codeunit "AU Exp. GL Account"; + AUExpPostingGrp: Codeunit "AU Exp. Posting Grp"; + begin + BindSubscription(AUExpGLAccount); + BindSubscription(AUExpPostingGrp); + + W1CountryData.CreateSetupData(); + Codeunit.Run(Codeunit::"AU Upd. Emp. Posting Grp"); + Codeunit.Run(Codeunit::"AU Exp. Posting Grp"); + + UnbindSubscription(AUExpPostingGrp); + UnbindSubscription(AUExpGLAccount); + end; + + procedure CreateMasterData() + var + W1CountryData: Codeunit "W1 Country Data"; + begin + W1CountryData.CreateMasterData(); + Codeunit.Run(Codeunit::"AU Exp. Categories"); + Codeunit.Run(Codeunit::"AU Exp. SubCategories"); + Codeunit.Run(Codeunit::"AU Exp. Rule Header"); + Codeunit.Run(Codeunit::"AU Exp. Rule Condition"); + end; + + procedure CreateTransactionalData() + var + W1CountryData: Codeunit "W1 Country Data"; + begin + W1CountryData.CreateTransactionalData(); + Codeunit.Run(Codeunit::"AU Expense"); + end; + + procedure CreateHistoricalData() + var + W1CountryData: Codeunit "W1 Country Data"; + AUPostedExpReport: Codeunit "AU Posted Exp. Report"; + begin + BindSubscription(AUPostedExpReport); + + W1CountryData.CreateHistoricalData(); + Codeunit.Run(Codeunit::"AU Posted Exp. Report"); + + UnbindSubscription(AUPostedExpReport); + end; +} diff --git a/src/Apps/W1/ExpenseAgent/demo data/Country/AU/AUExpCategories.Codeunit.al b/src/Apps/W1/ExpenseAgent/demo data/Country/AU/AUExpCategories.Codeunit.al new file mode 100644 index 00000000000..e70cdbe067d --- /dev/null +++ b/src/Apps/W1/ExpenseAgent/demo data/Country/AU/AUExpCategories.Codeunit.al @@ -0,0 +1,31 @@ +// ------------------------------------------------------------------------------------------------ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. See License.txt in the project root for license information. +// ------------------------------------------------------------------------------------------------ +namespace Microsoft.ExpenseAgent; + +codeunit 8269 "AU Exp. Categories" +{ + InherentEntitlements = X; + InherentPermissions = X; + + trigger OnRun() + var + CreateExpenseGroup: Codeunit "Create Expense Group"; + CreateExpensePaymentMethod: Codeunit "Create Expense Payment Method"; + ContosoExpenseAgent: Codeunit "Contoso Expense Agent"; + AUExpPostingGrp: Codeunit "AU Exp. Posting Grp"; + begin + ContosoExpenseAgent.InsertExpenseCategory(PerDiem(), PerDiemByAssignedPolicyLbl, PerDiemByAssignedPolicyPostingLbl, AUExpPostingGrp.ExpensePerDiem(), Enum::"Expense Attachment Enforcement"::" ", CreateExpensePaymentMethod.Cash(), false, false, CreateExpenseGroup.Travel(), true, Enum::"Expense Reimbursement Type"::"Employee Paid", Enum::"Expense Detail Needed"::"Per Diem"); + end; + + var + PerDiemTok: Label 'PER-DIEM', MaxLength = 20, Locked = true; + PerDiemByAssignedPolicyLbl: Label 'Expenses for per-diem or daily allowance paid for business trips, typically based on travel itinerary or other proof of travel (e.g., booking or agenda), rather than individual expense receipts.', MaxLength = 250; + PerDiemByAssignedPolicyPostingLbl: Label 'Per-diem by assigned policy', MaxLength = 100; + + procedure PerDiem(): Code[20] + begin + exit(PerDiemTok); + end; +} diff --git a/src/Apps/W1/ExpenseAgent/demo data/Country/AU/AUExpGLAccount.Codeunit.al b/src/Apps/W1/ExpenseAgent/demo data/Country/AU/AUExpGLAccount.Codeunit.al new file mode 100644 index 00000000000..3308784413b --- /dev/null +++ b/src/Apps/W1/ExpenseAgent/demo data/Country/AU/AUExpGLAccount.Codeunit.al @@ -0,0 +1,60 @@ +// ------------------------------------------------------------------------------------------------ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. See License.txt in the project root for license information. +// ------------------------------------------------------------------------------------------------ +namespace Microsoft.ExpenseAgent; + +using Microsoft.DemoTool.Helpers; +using Microsoft.Finance.GeneralLedger.Account; +using Microsoft.Foundation.Enums; + +codeunit 8266 "AU Exp. GL Account" +{ + SingleInstance = true; + EventSubscriberInstance = Manual; + InherentEntitlements = X; + InherentPermissions = X; + + [EventSubscriber(ObjectType::Codeunit, Codeunit::"Create Expense G/L Account", 'OnAfterAddGLAccountsForLocalization', '', false, false)] + local procedure ModifyGLAccount() + var + GLAccountCategory: Record "G/L Account Category"; + SubCategory: Text[80]; + begin + AddGLAccounts(); + + SubCategory := Format(GLAccountCategory."Account Category"::Assets, 80); + ContosoGLAccount.InsertGLAccount(ExpenseGLAccount.CompanyCreditCardsAccount(), ExpenseGLAccount.CompanyCreditCardsAccountName(), "G/L Account Income/Balance"::"Balance Sheet", Enum::"G/L Account Category"::Assets, SubCategory, Enum::"G/L Account Type"::Posting, '', '', '', 0, '', Enum::"General Posting Type"::" ", '', '', true, false, false); + ContosoGLAccount.InsertGLAccount(ExpenseGLAccount.EmployeePrepaymentsExpensesAccount(), ExpenseGLAccount.EmployeePrepaymentsExpensesAccountName(), "G/L Account Income/Balance"::"Balance Sheet", Enum::"G/L Account Category"::Assets, SubCategory, Enum::"G/L Account Type"::Posting, '', '', '', 0, '', Enum::"General Posting Type"::" ", '', '', true, false, false); + + SubCategory := Format(GLAccountCategory."Account Category"::Expense, 80); + ContosoGLAccount.InsertGLAccount(ExpenseGLAccount.PerDiemTravelExpensesAccount(), ExpenseGLAccount.PerDiemTravelExpensesAccountName(), "G/L Account Income/Balance"::"Income Statement", Enum::"G/L Account Category"::Expense, SubCategory, Enum::"G/L Account Type"::Posting, '', '', '', 0, '', Enum::"General Posting Type"::Purchase, '', '', true, false, false); + ContosoGLAccount.InsertGLAccount(ExpenseGLAccount.MileageTravelExpensesAccount(), ExpenseGLAccount.MileageTravelExpensesAccountName(), "G/L Account Income/Balance"::"Income Statement", Enum::"G/L Account Category"::Expense, SubCategory, Enum::"G/L Account Type"::Posting, '', '', '', 0, '', Enum::"General Posting Type"::Purchase, '', '', true, false, false); + ContosoGLAccount.InsertGLAccount(ExpenseGLAccount.MealExpensesDeductibleAccount(), ExpenseGLAccount.MealExpensesDeductibleAccountName(), "G/L Account Income/Balance"::"Income Statement", Enum::"G/L Account Category"::Expense, SubCategory, Enum::"G/L Account Type"::Posting, '', '', '', 0, '', Enum::"General Posting Type"::Purchase, '', '', true, false, false); + ContosoGLAccount.InsertGLAccount(ExpenseGLAccount.MealExpensesNondeductibleAccount(), ExpenseGLAccount.MealExpensesNondeductibleAccountName(), "G/L Account Income/Balance"::"Income Statement", Enum::"G/L Account Category"::Expense, SubCategory, Enum::"G/L Account Type"::Posting, '', '', '', 0, '', Enum::"General Posting Type"::Purchase, '', '', true, false, false); + ContosoGLAccount.InsertGLAccount(ExpenseGLAccount.OtherNondeductibleTravelExpensesAccount(), ExpenseGLAccount.OtherNondeductibleTravelExpensesAccountName(), "G/L Account Income/Balance"::"Income Statement", Enum::"G/L Account Category"::Expense, SubCategory, Enum::"G/L Account Type"::Posting, '', '', '', 0, '', Enum::"General Posting Type"::Purchase, '', '', true, false, false); + ContosoGLAccount.InsertGLAccount(ExpenseGLAccount.MiscExternalExpensesNondeductibleAccount(), ExpenseGLAccount.MiscExternalExpensesNondeductibleAccountName(), "G/L Account Income/Balance"::"Income Statement", Enum::"G/L Account Category"::Expense, SubCategory, Enum::"G/L Account Type"::Posting, '', '', '', 0, '', Enum::"General Posting Type"::Purchase, '', '', true, false, false); + ContosoGLAccount.InsertGLAccount(ExpenseGLAccount.RentalVehiclesAccount(), ExpenseGLAccount.RentalVehiclesAccountName(), "G/L Account Income/Balance"::"Income Statement", Enum::"G/L Account Category"::Expense, SubCategory, Enum::"G/L Account Type"::Posting, '', '', '', 0, '', Enum::"General Posting Type"::Purchase, '', '', true, false, false); + ContosoGLAccount.InsertGLAccount(ExpenseGLAccount.BusinessEntertainingNondeductibleAccount(), ExpenseGLAccount.BusinessEntertainingNondeductibleAccountName(), "G/L Account Income/Balance"::"Income Statement", Enum::"G/L Account Category"::Expense, SubCategory, Enum::"G/L Account Type"::Posting, '', '', '', 0, '', Enum::"General Posting Type"::Purchase, '', '', true, false, false); + ContosoGLAccount.InsertGLAccount(ExpenseGLAccount.OtherTravelExpensesAccount(), ExpenseGLAccount.OtherTravelExpensesAccountName(), "G/L Account Income/Balance"::"Income Statement", Enum::"G/L Account Category"::Expense, SubCategory, Enum::"G/L Account Type"::Posting, '', '', '', 0, '', Enum::"General Posting Type"::Purchase, '', '', true, false, false); + end; + + local procedure AddGLAccounts() + begin + ContosoGLAccount.AddAccountForLocalization(ExpenseGLAccount.CompanyCreditCardsAccountName(), '1025'); + ContosoGLAccount.AddAccountForLocalization(ExpenseGLAccount.EmployeePrepaymentsExpensesAccountName(), '1512'); + ContosoGLAccount.AddAccountForLocalization(ExpenseGLAccount.PerDiemTravelExpensesAccountName(), '6246'); + ContosoGLAccount.AddAccountForLocalization(ExpenseGLAccount.MileageTravelExpensesAccountName(), '6247'); + ContosoGLAccount.AddAccountForLocalization(ExpenseGLAccount.MealExpensesDeductibleAccountName(), '6248'); + ContosoGLAccount.AddAccountForLocalization(ExpenseGLAccount.MealExpensesNondeductibleAccountName(), '6237'); + ContosoGLAccount.AddAccountForLocalization(ExpenseGLAccount.OtherNondeductibleTravelExpensesAccountName(), '6416'); + ContosoGLAccount.AddAccountForLocalization(ExpenseGLAccount.MiscExternalExpensesNondeductibleAccountName(), '6415'); + ContosoGLAccount.AddAccountForLocalization(ExpenseGLAccount.RentalVehiclesAccountName(), '6250'); + ContosoGLAccount.AddAccountForLocalization(ExpenseGLAccount.BusinessEntertainingNondeductibleAccountName(), '6236'); + ContosoGLAccount.AddAccountForLocalization(ExpenseGLAccount.OtherTravelExpensesAccountName(), '6249'); + end; + + var + ContosoGLAccount: Codeunit "Contoso GL Account"; + ExpenseGLAccount: Codeunit "Create Expense G/L Account"; +} diff --git a/src/Apps/W1/ExpenseAgent/demo data/Country/AU/AUExpPostingGrp.Codeunit.al b/src/Apps/W1/ExpenseAgent/demo data/Country/AU/AUExpPostingGrp.Codeunit.al new file mode 100644 index 00000000000..fbd87d448d7 --- /dev/null +++ b/src/Apps/W1/ExpenseAgent/demo data/Country/AU/AUExpPostingGrp.Codeunit.al @@ -0,0 +1,65 @@ +// ------------------------------------------------------------------------------------------------ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. See License.txt in the project root for license information. +// ------------------------------------------------------------------------------------------------ +namespace Microsoft.ExpenseAgent; + +using Microsoft.DemoData.Finance; + +codeunit 8267 "AU Exp. Posting Grp" +{ + SingleInstance = true; + EventSubscriberInstance = Manual; + InherentEntitlements = X; + InherentPermissions = X; + + trigger OnRun() + var + ContosoExpenseAgent: Codeunit "Contoso Expense Agent"; + begin + ContosoExpenseAgent.InsertExpensePostingGroup(ExpensePerDiem(), ExpensePerDiemLbl); + end; + + [EventSubscriber(ObjectType::Table, Database::"Expense Posting Group", 'OnBeforeInsertEvent', '', false, false)] + local procedure OnInsertRecord(var Rec: Record "Expense Posting Group") + var + CreateGLAccount: Codeunit "Create G/L Account"; + ExpenseGLAccount: Codeunit "Create Expense G/L Account"; + CreateExpensePostingGroup: Codeunit "Create Expense Posting Group"; + begin + case Rec.Code of + CreateExpensePostingGroup.ExpenseEntertainment(): + ValidateRecordFields(Rec, ExpenseGLAccount.FindGLAccountByName(CreateGLAccount.EntertainmentandPRName()), ExpenseGLAccount.FindGLAccountByName(CreateGLAccount.FinanceChargestoVendorsName()), ExpenseGLAccount.EmployeePrepaymentsExpensesAccount(), ExpenseGLAccount.FindGLAccountByName(CreateGLAccount.InvoiceRoundingName()), ExpenseGLAccount.FindGLAccountByName(CreateGLAccount.InvoiceRoundingName())); + CreateExpensePostingGroup.ExpenseMeals(): + ValidateRecordFields(Rec, ExpenseGLAccount.MealExpensesDeductibleAccount(), ExpenseGLAccount.FindGLAccountByName(CreateGLAccount.FinanceChargestoVendorsName()), ExpenseGLAccount.EmployeePrepaymentsExpensesAccount(), ExpenseGLAccount.FindGLAccountByName(CreateGLAccount.InvoiceRoundingName()), ExpenseGLAccount.FindGLAccountByName(CreateGLAccount.InvoiceRoundingName())); + CreateExpensePostingGroup.ExpenseMileage(): + ValidateRecordFields(Rec, ExpenseGLAccount.MileageTravelExpensesAccount(), '', ExpenseGLAccount.EmployeePrepaymentsExpensesAccount(), ExpenseGLAccount.FindGLAccountByName(CreateGLAccount.InvoiceRoundingName()), ExpenseGLAccount.FindGLAccountByName(CreateGLAccount.InvoiceRoundingName())); + CreateExpensePostingGroup.ExpenseOther(): + ValidateRecordFields(Rec, ExpenseGLAccount.BusinessEntertainingNondeductibleAccount(), ExpenseGLAccount.FindGLAccountByName(CreateGLAccount.FinanceChargestoVendorsName()), ExpenseGLAccount.EmployeePrepaymentsExpensesAccount(), ExpenseGLAccount.FindGLAccountByName(CreateGLAccount.InvoiceRoundingName()), ExpenseGLAccount.FindGLAccountByName(CreateGLAccount.InvoiceRoundingName())); + ExpensePerDiem(): + ValidateRecordFields(Rec, ExpenseGLAccount.PerDiemTravelExpensesAccount(), '', ExpenseGLAccount.EmployeePrepaymentsExpensesAccount(), ExpenseGLAccount.FindGLAccountByName(CreateGLAccount.InvoiceRoundingName()), ExpenseGLAccount.FindGLAccountByName(CreateGLAccount.InvoiceRoundingName())); + CreateExpensePostingGroup.ExpenseTravel(): + ValidateRecordFields(Rec, ExpenseGLAccount.OtherTravelExpensesAccount(), ExpenseGLAccount.FindGLAccountByName(CreateGLAccount.FinanceChargestoVendorsName()), ExpenseGLAccount.EmployeePrepaymentsExpensesAccount(), ExpenseGLAccount.FindGLAccountByName(CreateGLAccount.InvoiceRoundingName()), ExpenseGLAccount.FindGLAccountByName(CreateGLAccount.InvoiceRoundingName())); + CreateExpensePostingGroup.ExpenseRentalCars(): + ValidateRecordFields(Rec, ExpenseGLAccount.RentalVehiclesAccount(), ExpenseGLAccount.FindGLAccountByName(CreateGLAccount.FinanceChargestoVendorsName()), ExpenseGLAccount.EmployeePrepaymentsExpensesAccount(), ExpenseGLAccount.FindGLAccountByName(CreateGLAccount.InvoiceRoundingName()), ExpenseGLAccount.FindGLAccountByName(CreateGLAccount.InvoiceRoundingName())); + end; + end; + + local procedure ValidateRecordFields(var ExpensePostingGroup: Record "Expense Posting Group"; RefundableDebitAccount: Code[20]; NonRefundableDebitAccount: Code[20]; PrepaymentCreditAccount: Code[20]; ExpenseDebitRoundingAccount: Code[20]; ExpenseCreditRoundingAccount: Code[20]) + begin + ExpensePostingGroup.Validate("Refundable Debit Account", RefundableDebitAccount); + ExpensePostingGroup.Validate("Non-Refundable Debit Account", NonRefundableDebitAccount); + ExpensePostingGroup.Validate("Prepayment Credit Account", PrepaymentCreditAccount); + ExpensePostingGroup.Validate("Debit Rounding Account", ExpenseDebitRoundingAccount); + ExpensePostingGroup.Validate("Credit Rounding Account", ExpenseCreditRoundingAccount); + end; + + var + ExpensePERDIEMTok: Label 'EXPENSE-PERDIEM', MaxLength = 20, Locked = true; + ExpensePerDiemLbl: Label 'Expense - Per Diem', MaxLength = 100; + + procedure ExpensePerDiem(): Code[20] + begin + exit(ExpensePERDIEMTok); + end; +} diff --git a/src/Apps/W1/ExpenseAgent/demo data/Country/AU/AUExpRuleCondition.Codeunit.al b/src/Apps/W1/ExpenseAgent/demo data/Country/AU/AUExpRuleCondition.Codeunit.al new file mode 100644 index 00000000000..f7e977cc3b1 --- /dev/null +++ b/src/Apps/W1/ExpenseAgent/demo data/Country/AU/AUExpRuleCondition.Codeunit.al @@ -0,0 +1,26 @@ +// ------------------------------------------------------------------------------------------------ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. See License.txt in the project root for license information. +// ------------------------------------------------------------------------------------------------ +namespace Microsoft.ExpenseAgent; + +codeunit 8272 "AU Exp. Rule Condition" +{ + InherentEntitlements = X; + InherentPermissions = X; + + trigger OnRun() + var + AUExpCategories: Codeunit "AU Exp. Categories"; + CreateExpenseLocation: Codeunit "Create Expense Location"; + ContosoExpenseAgent: Codeunit "Contoso Expense Agent"; + begin + ContosoExpenseAgent.InsertExpenseRuleCondition(AUExpCategories.PerDiem(), CreateExpenseLocation.CanadaAll(), 0D, 10000, Enum::"Expense Rule Condition Type"::"Daily Rate", 125); + ContosoExpenseAgent.InsertExpenseRuleCondition(AUExpCategories.PerDiem(), CreateExpenseLocation.DenmarkAll(), 0D, 10000, Enum::"Expense Rule Condition Type"::"Daily Rate", 450); + ContosoExpenseAgent.InsertExpenseRuleCondition(AUExpCategories.PerDiem(), CreateExpenseLocation.Domestic(), 0D, 10000, Enum::"Expense Rule Condition Type"::"Daily Rate", 50); + ContosoExpenseAgent.InsertExpenseRuleCondition(AUExpCategories.PerDiem(), CreateExpenseLocation.FranceAll(), 0D, 10000, Enum::"Expense Rule Condition Type"::"Daily Rate", 110); + ContosoExpenseAgent.InsertExpenseRuleCondition(AUExpCategories.PerDiem(), CreateExpenseLocation.GermanyAll(), 0D, 10000, Enum::"Expense Rule Condition Type"::"Daily Rate", 105); + ContosoExpenseAgent.InsertExpenseRuleCondition(AUExpCategories.PerDiem(), CreateExpenseLocation.UKOther(), 0D, 10000, Enum::"Expense Rule Condition Type"::"Daily Rate", 115); + ContosoExpenseAgent.InsertExpenseRuleCondition(AUExpCategories.PerDiem(), CreateExpenseLocation.USAOther(), 0D, 10000, Enum::"Expense Rule Condition Type"::"Daily Rate", 120); + end; +} diff --git a/src/Apps/W1/ExpenseAgent/demo data/Country/AU/AUExpRuleHeader.Codeunit.al b/src/Apps/W1/ExpenseAgent/demo data/Country/AU/AUExpRuleHeader.Codeunit.al new file mode 100644 index 00000000000..1539a091850 --- /dev/null +++ b/src/Apps/W1/ExpenseAgent/demo data/Country/AU/AUExpRuleHeader.Codeunit.al @@ -0,0 +1,29 @@ +// ------------------------------------------------------------------------------------------------ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. See License.txt in the project root for license information. +// ------------------------------------------------------------------------------------------------ +namespace Microsoft.ExpenseAgent; + +using Microsoft.DemoData.Finance; + +codeunit 8271 "AU Exp. Rule Header" +{ + InherentEntitlements = X; + InherentPermissions = X; + + trigger OnRun() + var + CreateCurrency: Codeunit "Create Currency"; + AUExpCategories: Codeunit "AU Exp. Categories"; + CreateExpenseLocation: Codeunit "Create Expense Location"; + ContosoExpenseAgent: Codeunit "Contoso Expense Agent"; + begin + ContosoExpenseAgent.InsertExpenseRuleHeader(AUExpCategories.PerDiem(), CreateExpenseLocation.CanadaAll(), 0D, Enum::"Expense Justification"::" ", false, '', CreateCurrency.CAD(), ''); + ContosoExpenseAgent.InsertExpenseRuleHeader(AUExpCategories.PerDiem(), CreateExpenseLocation.DenmarkAll(), 0D, Enum::"Expense Justification"::" ", false, '', CreateCurrency.EUR(), ''); + ContosoExpenseAgent.InsertExpenseRuleHeader(AUExpCategories.PerDiem(), CreateExpenseLocation.Domestic(), 0D, Enum::"Expense Justification"::" ", false, '', '', ''); + ContosoExpenseAgent.InsertExpenseRuleHeader(AUExpCategories.PerDiem(), CreateExpenseLocation.FranceAll(), 0D, Enum::"Expense Justification"::" ", false, '', CreateCurrency.EUR(), ''); + ContosoExpenseAgent.InsertExpenseRuleHeader(AUExpCategories.PerDiem(), CreateExpenseLocation.GermanyAll(), 0D, Enum::"Expense Justification"::" ", false, '', CreateCurrency.EUR(), ''); + ContosoExpenseAgent.InsertExpenseRuleHeader(AUExpCategories.PerDiem(), CreateExpenseLocation.UKOther(), 0D, Enum::"Expense Justification"::" ", false, '', CreateCurrency.GBP(), ''); + ContosoExpenseAgent.InsertExpenseRuleHeader(AUExpCategories.PerDiem(), CreateExpenseLocation.USAOther(), 0D, Enum::"Expense Justification"::" ", false, '', '', ''); + end; +} diff --git a/src/Apps/W1/ExpenseAgent/demo data/Country/AU/AUExpSubCategories.Codeunit.al b/src/Apps/W1/ExpenseAgent/demo data/Country/AU/AUExpSubCategories.Codeunit.al new file mode 100644 index 00000000000..a237c36552f --- /dev/null +++ b/src/Apps/W1/ExpenseAgent/demo data/Country/AU/AUExpSubCategories.Codeunit.al @@ -0,0 +1,39 @@ +// ------------------------------------------------------------------------------------------------ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. See License.txt in the project root for license information. +// ------------------------------------------------------------------------------------------------ +namespace Microsoft.ExpenseAgent; + +codeunit 8270 "AU Exp. SubCategories" +{ + InherentEntitlements = X; + InherentPermissions = X; + + trigger OnRun() + var + ContosoExpenseAgent: Codeunit "Contoso Expense Agent"; + AUExpCategories: Codeunit "AU Exp. Categories"; + begin + // PER-DIEM subcategories + ContosoExpenseAgent.InsertExpenseSubcategory(Country(), AUExpCategories.PerDiem(), LocalCountryPerDiemLbl, LocalCountryPerDiemPostingLbl, false, true, false); + ContosoExpenseAgent.InsertExpenseSubcategory(Intl(), AUExpCategories.PerDiem(), InternationalPerDiemLbl, InternationalPerDiemPostingLbl, false, true, false); + end; + + var + CountryTok: Label 'COUNTRY', MaxLength = 20, Locked = true; + IntlTok: Label 'INTL', MaxLength = 20, Locked = true; + LocalCountryPerDiemLbl: Label 'Daily per-diem allowance based on domestic travel rates, paid instead of individual meal or incidental expense reimbursements.', MaxLength = 250; + InternationalPerDiemLbl: Label 'Daily per-diem allowance for international business travel, based on applicable foreign travel rates.', MaxLength = 250; + LocalCountryPerDiemPostingLbl: Label 'Local country per-diem', MaxLength = 100; + InternationalPerDiemPostingLbl: Label 'International per-diem', MaxLength = 100; + + procedure Country(): Code[20] + begin + exit(CountryTok); + end; + + procedure Intl(): Code[20] + begin + exit(IntlTok); + end; +} diff --git a/src/Apps/W1/ExpenseAgent/demo data/Country/AU/AUExpense.Codeunit.al b/src/Apps/W1/ExpenseAgent/demo data/Country/AU/AUExpense.Codeunit.al new file mode 100644 index 00000000000..da9c5ebe688 --- /dev/null +++ b/src/Apps/W1/ExpenseAgent/demo data/Country/AU/AUExpense.Codeunit.al @@ -0,0 +1,51 @@ +// ------------------------------------------------------------------------------------------------ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. See License.txt in the project root for license information. +// ------------------------------------------------------------------------------------------------ +namespace Microsoft.ExpenseAgent; + +using Microsoft.DemoTool.Helpers; + +codeunit 8273 "AU Expense" +{ + InherentEntitlements = X; + InherentPermissions = X; + Permissions = tabledata "Expense Per Diem" = rim; + + trigger OnRun() + begin + CreateOpenExpense(); + end; + + local procedure CreateOpenExpense() + var + Expense: Record Expense; + ContosoExpenseAgent: Codeunit "Contoso Expense Agent"; + CreateExpenseLocation: Codeunit "Create Expense Location"; + begin + Expense := ContosoExpenseAgent.InsertExpense(CreateExpenseUser.EH(), AUExpCategories.PerDiem(), CreateExpenseLocation.DenmarkAll(), PerDiemByAssignedPolicyLbl, '', ContosoUtility.AdjustDate(19030203D), '', 0, '', CreateExpensePaymentMethod.Cash(), true, false, '', CreateDateTime(ContosoUtility.AdjustDate(19030115D), 144000T), CreateDateTime(ContosoUtility.AdjustDate(19030121D), 000500T), 0, 0, '', '', '', '', ''); + UpdateExpensePerDiem(Expense."No.", 10000, false, false, true); + UpdateExpensePerDiem(Expense."No.", 30000, false, true, false); + UpdateExpensePerDiem(Expense."No.", 40000, false, false, true); + UpdateExpensePerDiem(Expense."No.", 60000, false, true, true); + end; + + var + ContosoUtility: Codeunit "Contoso Utilities"; + CreateExpenseUser: Codeunit "Create Expense User"; + AUExpCategories: Codeunit "AU Exp. Categories"; + CreateExpensePaymentMethod: Codeunit "Create Expense Payment Method"; + PerDiemByAssignedPolicyLbl: Label 'Per-diem by assigned policy', MaxLength = 100; + + local procedure UpdateExpensePerDiem(ExpenseNo: Code[20]; LineNo: Integer; Breakfast: Boolean; Lunch: Boolean; Dinner: Boolean) + var + ExpensePerDiem: Record "Expense Per Diem"; + begin + ExpensePerDiem.Get(ExpenseNo, LineNo); + + ExpensePerDiem.Validate(Breakfast, Breakfast); + ExpensePerDiem.Validate(Lunch, Lunch); + ExpensePerDiem.Validate(Dinner, Dinner); + ExpensePerDiem.Modify(); + end; +} diff --git a/src/Apps/W1/ExpenseAgent/demo data/Country/AU/AUPostedExpReport.Codeunit.al b/src/Apps/W1/ExpenseAgent/demo data/Country/AU/AUPostedExpReport.Codeunit.al new file mode 100644 index 00000000000..11861cb44c8 --- /dev/null +++ b/src/Apps/W1/ExpenseAgent/demo data/Country/AU/AUPostedExpReport.Codeunit.al @@ -0,0 +1,168 @@ +// ------------------------------------------------------------------------------------------------ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. See License.txt in the project root for license information. +// ------------------------------------------------------------------------------------------------ +namespace Microsoft.ExpenseAgent; + +using Microsoft.DemoData.Finance; +using Microsoft.DemoData.HumanResources; +using Microsoft.DemoTool.Helpers; + +codeunit 8274 "AU Posted Exp. Report" +{ + SingleInstance = true; + EventSubscriberInstance = Manual; + InherentEntitlements = X; + InherentPermissions = X; + Permissions = + tabledata "Expense Per Diem" = rim, + tabledata "Expense Report Line" = rim; + + trigger OnRun() + var + ExpenseReportHeader: Record "Expense Report Header"; + begin + if ExpenseReportHeader.FindLast() then + FromExpenseReportNo := ExpenseReportHeader."No."; + + CreateExpenseReportToPost(); + + PostExpenseReport(); + end; + + [EventSubscriber(ObjectType::Codeunit, Codeunit::"Create Posted Expense Report", OnDefineExpenseAccountNo, '', false, false)] + local procedure OnDefineExpenseAccountNo(var AccountNo: Code[20]) + var + CreateGLAccount: Codeunit "Create G/L Account"; + ExpenseGLAccount: Codeunit "Create Expense G/L Account"; + begin + AccountNo := ExpenseGLAccount.FindGLAccountByName(CreateGLAccount.SalesResourcesExportName()); + end; + + local procedure CreateExpenseReportToPost() + var + Expense: Record Expense; + ExpenseReportHeader: Record "Expense Report Header"; + CreateEmployee: Codeunit "Create Employee"; + CreateCurrency: Codeunit "Create Currency"; + ContosoUtility: Codeunit "Contoso Utilities"; + CreateExpenseUser: Codeunit "Create Expense User"; + CreateExpenseLocation: Codeunit "Create Expense Location"; + ContosoExpenseAgent: Codeunit "Contoso Expense Agent"; + CreateExpCategories: Codeunit "Create Expense Categories DM"; + AUExpCategories: Codeunit "AU Exp. Categories"; + CreateExpenseSubcategories: Codeunit "Create Expense Subcategories"; + CreateExpensePaymentMethod: Codeunit "Create Expense Payment Method"; + begin + ExpenseReportHeader := ContosoExpenseAgent.InsertExpenseReportHeader(CreateExpenseUser.JO(), ContosoUtility.AdjustDate(19021104D), ContosoUtility.AdjustDate(19021104D)); + Expense := ContosoExpenseAgent.InsertExpense(CreateExpenseUser.JO(), AUExpCategories.PerDiem(), CreateExpenseLocation.GermanyAll(), BusinessTripToHamburgLbl, '', ContosoUtility.AdjustDate(19021103D), '', 0, '', CreateExpensePaymentMethod.Cash(), true, false, '', CreateDateTime(ContosoUtility.AdjustDate(19021024D), 064500T), CreateDateTime(ContosoUtility.AdjustDate(19021027D), 161500T), 0, 0, '', '', '', '', ''); + ReleaseAndAddExpenseToExpenseReport(Expense, ExpenseReportHeader); + Expense := ContosoExpenseAgent.InsertExpense(CreateExpenseUser.JO(), CreateExpCategories.Airline(), '', AirlineTicketsLbl, '', ContosoUtility.AdjustDate(19021010D), '', 2042, MargieTravelLbl, CreateExpensePaymentMethod.Card(), true, false, '', 0DT, 0DT, 0, 0, '', '', 'TY6HJO', '', ''); + ReleaseAndAddExpenseToExpenseReport(Expense, ExpenseReportHeader); + + ExpenseReportHeader := ContosoExpenseAgent.InsertExpenseReportHeader(CreateExpenseUser.EH(), ContosoUtility.AdjustDate(19021204D), ContosoUtility.AdjustDate(19021204D)); + Expense := ContosoExpenseAgent.InsertExpense(CreateExpenseUser.EH(), CreateExpCategories.Airline(), '', AirlineTicketsDublinLbl, TravelToConferenceLbl, ContosoUtility.AdjustDate(19021106D), '', 3120, MargieTravelLbl, CreateExpensePaymentMethod.Card(), true, false, '', 0DT, 0DT, 0, 0, '', '', 'FIUXHJT', '', ''); + ReleaseAndAddExpenseToExpenseReport(Expense, ExpenseReportHeader); + Expense := ContosoExpenseAgent.InsertExpense(CreateExpenseUser.EH(), CreateExpCategories.Events(), '', ITConferenceLbl, '', ContosoUtility.AdjustDate(19021107D), CreateCurrency.EUR(), 1990, ProsewareIncLbl, CreateExpensePaymentMethod.Card(), true, false, '', 0DT, 0DT, 0, 0, '', '', 'G574576HJ656', '', ''); + ReleaseAndAddExpenseToExpenseReport(Expense, ExpenseReportHeader); + Expense := ContosoExpenseAgent.InsertExpense(CreateExpenseUser.EH(), CreateExpCategories.GroundTransportation(), '', TaxiLbl, '', ContosoUtility.AdjustDate(19021114D), CreateCurrency.EUR(), 45, TailwindTradersLbl, CreateExpensePaymentMethod.Cash(), true, false, '', 0DT, 0DT, 0, 0, '', '', '456845856867', '', ''); + ReleaseAndAddExpenseToExpenseReport(Expense, ExpenseReportHeader); + Expense := ContosoExpenseAgent.InsertExpense(CreateExpenseUser.EH(), CreateExpCategories.Entertain(), '', BusinessDinnerLbl, BusinessDinnerWithBigPotentialCustomersLbl, ContosoUtility.AdjustDate(19021116D), CreateCurrency.EUR(), 842, FourthCoffeeLbl, CreateExpensePaymentMethod.Card(), true, false, '', 0DT, 0DT, 0, 0, '', '', 'RT6457560034', '', ''); + ContosoExpenseAgent.InsertExpenseParticipant(Expense."No.", 10000, CreateExpCategories.Entertain(), Enum::"Expense Participant Type"::Employee, CreateEmployee.ManagingDirector(), '', '', '', '', ''); + ContosoExpenseAgent.InsertExpenseParticipant(Expense."No.", 20000, CreateExpCategories.Entertain(), Enum::"Expense Participant Type"::Employee, CreateEmployee.SalesManager(), '', '', '', '', ''); + ContosoExpenseAgent.InsertExpenseParticipant(Expense."No.", 30000, CreateExpCategories.Entertain(), Enum::"Expense Participant Type"::External, '', JesseHomerLbl, RelecloudLbl, '', CEOLbl, 'jesse.homer@contoso.com'); + ContosoExpenseAgent.InsertExpenseParticipant(Expense."No.", 40000, CreateExpCategories.Entertain(), Enum::"Expense Participant Type"::External, '', RobertTownesLbl, AdatumCorporationLbl, '', CEOLbl, 'robert.townes@contoso.com'); + ReleaseAndAddExpenseToExpenseReport(Expense, ExpenseReportHeader); + Expense := ContosoExpenseAgent.InsertExpense(CreateExpenseUser.EH(), CreateExpCategories.Hotels(), '', HotelStayLbl, '', ContosoUtility.AdjustDate(19021118D), CreateCurrency.EUR(), 2150, ContosoSuitesLbl, CreateExpensePaymentMethod.Card(), true, false, '', 0DT, 0DT, 0, 0, '', '', '64675S879CT987990004', '', ''); + ContosoExpenseAgent.InsertExpenseItemization(Expense."No.", 10000, CreateExpCategories.Hotels(), CreateExpenseSubcategories.Room(), AccommodationLbl, ContosoUtility.AdjustDate(19021114D), 390); + ContosoExpenseAgent.InsertExpenseItemization(Expense."No.", 20000, CreateExpCategories.Hotels(), CreateExpenseSubcategories.Breakfast(), BreakfastLbl, ContosoUtility.AdjustDate(19021115D), 35); + ContosoExpenseAgent.InsertExpenseItemization(Expense."No.", 30000, CreateExpCategories.Hotels(), CreateExpenseSubcategories.Room(), AccommodationLbl, ContosoUtility.AdjustDate(19021115D), 390); + ContosoExpenseAgent.InsertExpenseItemization(Expense."No.", 40000, CreateExpCategories.Hotels(), CreateExpenseSubcategories.Breakfast(), BreakfastLbl, ContosoUtility.AdjustDate(19021116D), 35); + ContosoExpenseAgent.InsertExpenseItemization(Expense."No.", 50000, CreateExpCategories.Hotels(), CreateExpenseSubcategories.Room(), AccommodationLbl, ContosoUtility.AdjustDate(19021116D), 390); + ContosoExpenseAgent.InsertExpenseItemization(Expense."No.", 60000, CreateExpCategories.Hotels(), CreateExpenseSubcategories.RoomService(), RoomServiceLbl, ContosoUtility.AdjustDate(19021116D), 145); + ContosoExpenseAgent.InsertExpenseItemization(Expense."No.", 70000, CreateExpCategories.Hotels(), CreateExpenseSubcategories.Breakfast(), BreakfastLbl, ContosoUtility.AdjustDate(19021117D), 35); + ContosoExpenseAgent.InsertExpenseItemization(Expense."No.", 80000, CreateExpCategories.Hotels(), CreateExpenseSubcategories.Room(), AccommodationLbl, ContosoUtility.AdjustDate(19021117D), 390); + ContosoExpenseAgent.InsertExpenseItemization(Expense."No.", 90000, CreateExpCategories.Hotels(), CreateExpenseSubcategories.Breakfast(), BreakfastLbl, ContosoUtility.AdjustDate(19021118D), 35); + ContosoExpenseAgent.InsertExpenseItemization(Expense."No.", 100000, CreateExpCategories.Hotels(), CreateExpenseSubcategories.Tax(), HotelTaxesLbl, ContosoUtility.AdjustDate(19021118D), 305); + ReleaseAndAddExpenseToExpenseReport(Expense, ExpenseReportHeader); + Expense := ContosoExpenseAgent.InsertExpense(CreateExpenseUser.EH(), CreateExpCategories.RentalCars(), '', CarRentalsLbl, '', ContosoUtility.AdjustDate(19021118D), CreateCurrency.EUR(), 622.45, VanArsdelLtdLbl, CreateExpensePaymentMethod.Card(), true, false, '', 0DT, 0DT, 0, 0, '', '', 'H6584769867J9J95789', '', ''); + ReleaseAndAddExpenseToExpenseReport(Expense, ExpenseReportHeader); + Expense := ContosoExpenseAgent.InsertExpense(CreateExpenseUser.EH(), CreateExpCategories.GroundTransportation(), '', TaxiLbl, '', ContosoUtility.AdjustDate(19021118D), CreateCurrency.EUR(), 71, TailwindTradersLbl, CreateExpensePaymentMethod.Cash(), true, false, '', 0DT, 0DT, 0, 0, '', '', '7456875687568', '', ''); + ReleaseAndAddExpenseToExpenseReport(Expense, ExpenseReportHeader); + Expense := ContosoExpenseAgent.InsertExpense(CreateExpenseUser.EH(), AUExpCategories.PerDiem(), CreateExpenseLocation.UKOther(), TripToUKLbl, '', ContosoUtility.AdjustDate(19021121D), '', 0, '', CreateExpensePaymentMethod.Cash(), true, false, '', CreateDateTime(ContosoUtility.AdjustDate(19021114D), 053000T), CreateDateTime(ContosoUtility.AdjustDate(19021118D), 220500T), 0, 0, '', '', '', '', ''); + UpdateExpensePerDiem(Expense."No.", 20000, false, false, true); + UpdateExpensePerDiem(Expense."No.", 40000, false, true, false); + ReleaseAndAddExpenseToExpenseReport(Expense, ExpenseReportHeader); + Expense := ContosoExpenseAgent.InsertExpense(CreateExpenseUser.EH(), AUExpCategories.PerDiem(), CreateExpenseLocation.Domestic(), TripToDoverLbl, '', ContosoUtility.AdjustDate(19021204D), '', 0, '', CreateExpensePaymentMethod.Cash(), true, false, '', CreateDateTime(ContosoUtility.AdjustDate(19021127D), 070000T), CreateDateTime(ContosoUtility.AdjustDate(19021129D), 145500T), 0, 0, '', '', '', '', ''); + ReleaseAndAddExpenseToExpenseReport(Expense, ExpenseReportHeader); + Expense := ContosoExpenseAgent.InsertExpense(CreateExpenseUser.EH(), CreateExpCategories.Mileage(), '', MileageLbl, '', ContosoUtility.AdjustDate(19031101D), '', 0, VanArsdelLtdLbl, CreateExpensePaymentMethod.Cash(), true, false, '', 0DT, 0DT, 0, 249, 'New York', 'Dover', 'H6584769867J9J95789', '', ''); + ReleaseAndAddExpenseToExpenseReport(Expense, ExpenseReportHeader); + end; + + var + FromExpenseReportNo: Code[20]; + BusinessTripToHamburgLbl: Label 'Business trip to Hamburg, DE', MaxLength = 100; + AirlineTicketsLbl: Label 'Airline tickets NY/FRANKFURT/HAMBURG/FRANKFURT/NY', MaxLength = 100; + MargieTravelLbl: Label 'Margie''s Travel', MaxLength = 100; + AirlineTicketsDublinLbl: Label 'Airline tickets NY/DUBLIN/NY', MaxLength = 100; + TravelToConferenceLbl: Label 'Travel to the conference', MaxLength = 100; + ITConferenceLbl: Label 'IT Conference', MaxLength = 100; + ProsewareIncLbl: Label 'Proseware, Inc.', MaxLength = 100; + TaxiLbl: Label 'Taxi', MaxLength = 100; + TailwindTradersLbl: Label 'Tailwind Traders', MaxLength = 100; + BusinessDinnerLbl: Label 'Business Dinner', MaxLength = 100; + BusinessDinnerWithBigPotentialCustomersLbl: Label 'Business dinner with a big potential customers', MaxLength = 100; + FourthCoffeeLbl: Label 'Fourth Coffee', MaxLength = 100; + JesseHomerLbl: Label 'Jesse Homer', MaxLength = 100; + RelecloudLbl: Label 'Relecloud', MaxLength = 100; + RobertTownesLbl: Label 'Robert Townes', MaxLength = 100; + AdatumCorporationLbl: Label 'Adatum Corporation', MaxLength = 100; + HotelStayLbl: Label 'Hotel stay', MaxLength = 100; + ContosoSuitesLbl: Label 'Contoso Suites', MaxLength = 100; + AccommodationLbl: Label 'Accommodation', MaxLength = 100; + BreakfastLbl: Label 'Breakfast', MaxLength = 100; + HotelTaxesLbl: Label 'Hotel Taxes', MaxLength = 100; + RoomServiceLbl: Label 'Room service', MaxLength = 100; + CarRentalsLbl: Label 'Car Rentals', MaxLength = 100; + VanArsdelLtdLbl: Label 'VanArsdel, Ltd.', MaxLength = 100; + TripToUKLbl: Label 'Trip to UK', MaxLength = 100; + TripToDoverLbl: Label 'Trip to Dover', MaxLength = 100; + MileageLbl: Label 'Mileage', MaxLength = 100; + CEOLbl: Label 'CEO', MaxLength = 30; + + local procedure ReleaseAndAddExpenseToExpenseReport(Expense: Record Expense; ExpenseReportHeader: Record "Expense Report Header") + var + ReleaseExpenseDocument: Codeunit "Release Expense Document"; + CreateExpenseReport: Codeunit "Create Expense Report"; + begin + Expense.Get(Expense."No."); + ReleaseExpenseDocument.Run(Expense); + + CreateExpenseReport.AddSingleExpenseToExpenseReport(Expense, ExpenseReportHeader); + end; + + local procedure PostExpenseReport() + var + ExpenseReportHeader: Record "Expense Report Header"; + begin + if FromExpenseReportNo <> '' then + ExpenseReportHeader.SetFilter("No.", '>%1', FromExpenseReportNo); + + if ExpenseReportHeader.FindSet() then + repeat + Codeunit.Run(Codeunit::"Expense Report-Post", ExpenseReportHeader); + until ExpenseReportHeader.Next() = 0; + end; + + local procedure UpdateExpensePerDiem(ExpenseNo: Code[20]; LineNo: Integer; Breakfast: Boolean; Lunch: Boolean; Dinner: Boolean) + var + ExpensePerDiem: Record "Expense Per Diem"; + begin + ExpensePerDiem.Get(ExpenseNo, LineNo); + + ExpensePerDiem.Validate(Breakfast, Breakfast); + ExpensePerDiem.Validate(Lunch, Lunch); + ExpensePerDiem.Validate(Dinner, Dinner); + ExpensePerDiem.Modify(); + end; +} diff --git a/src/Apps/W1/ExpenseAgent/demo data/Country/AU/AUUpdEmpPostingGrp.Codeunit.al b/src/Apps/W1/ExpenseAgent/demo data/Country/AU/AUUpdEmpPostingGrp.Codeunit.al new file mode 100644 index 00000000000..4e41480d7c6 --- /dev/null +++ b/src/Apps/W1/ExpenseAgent/demo data/Country/AU/AUUpdEmpPostingGrp.Codeunit.al @@ -0,0 +1,31 @@ +// ------------------------------------------------------------------------------------------------ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. See License.txt in the project root for license information. +// ------------------------------------------------------------------------------------------------ +namespace Microsoft.ExpenseAgent; + +using Microsoft.DemoData.Finance; +using Microsoft.DemoData.HumanResources; + +codeunit 8268 "AU Upd. Emp. Posting Grp" +{ + InherentEntitlements = X; + InherentPermissions = X; + + trigger OnRun() + begin + UpdateEmployeePostingGroup(); + end; + + local procedure UpdateEmployeePostingGroup() + var + CreateGLAccount: Codeunit "Create G/L Account"; + ExpenseGLAccount: Codeunit "Create Expense G/L Account"; + ContosoExpenseAgent: Codeunit "Contoso Expense Agent"; + CreateEmployeePostingGroup: Codeunit "Create Employee Posting Group"; + begin + ContosoExpenseAgent.SetOverwriteData(true); + ContosoExpenseAgent.UpdateEmployeePostingGroup(CreateEmployeePostingGroup.EmployeeExpenses(), ExpenseGLAccount.FindGLAccountByName(CreateGLAccount.EmployeesPayableName()), ExpenseGLAccount.EmployeePrepaymentsExpensesAccount(), ExpenseGLAccount.FindGLAccountByName(CreateGLAccount.BankLcyName()), ExpenseGLAccount.CompanyCreditCardsAccount()); + ContosoExpenseAgent.SetOverwriteData(false); + end; +} diff --git a/src/Apps/W1/ExpenseAgent/demo data/Country/CA/CACountryData.Codeunit.al b/src/Apps/W1/ExpenseAgent/demo data/Country/CA/CACountryData.Codeunit.al new file mode 100644 index 00000000000..77bda558d1d --- /dev/null +++ b/src/Apps/W1/ExpenseAgent/demo data/Country/CA/CACountryData.Codeunit.al @@ -0,0 +1,61 @@ +// ------------------------------------------------------------------------------------------------ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. See License.txt in the project root for license information. +// ------------------------------------------------------------------------------------------------ +namespace Microsoft.ExpenseAgent; + +codeunit 8245 "CA Country Data" implements "Expense Agent Country Data" +{ + Access = Internal; + InherentEntitlements = X; + InherentPermissions = X; + + procedure CreateSetupData() + var + W1CountryData: Codeunit "W1 Country Data"; + CAExpGLAccount: Codeunit "CA Exp. GL Account"; + CAExpPostingGrp: Codeunit "CA Exp. Posting Grp"; + begin + BindSubscription(CAExpGLAccount); + BindSubscription(CAExpPostingGrp); + + W1CountryData.CreateSetupData(); + Codeunit.Run(Codeunit::"CA Upd. Emp. Posting Grp"); + Codeunit.Run(Codeunit::"CA Exp. Posting Grp"); + + UnbindSubscription(CAExpPostingGrp); + UnbindSubscription(CAExpGLAccount); + end; + + procedure CreateMasterData() + var + W1CountryData: Codeunit "W1 Country Data"; + begin + W1CountryData.CreateMasterData(); + Codeunit.Run(Codeunit::"CA Exp. Categories"); + Codeunit.Run(Codeunit::"CA Exp. SubCategories"); + Codeunit.Run(Codeunit::"CA Exp. Rule Header"); + Codeunit.Run(Codeunit::"CA Exp. Rule Condition"); + end; + + procedure CreateTransactionalData() + var + W1CountryData: Codeunit "W1 Country Data"; + begin + W1CountryData.CreateTransactionalData(); + Codeunit.Run(Codeunit::"CA Expense"); + end; + + procedure CreateHistoricalData() + var + W1CountryData: Codeunit "W1 Country Data"; + CAPostedExpReport: Codeunit "CA Posted Exp. Report"; + begin + BindSubscription(CAPostedExpReport); + + W1CountryData.CreateHistoricalData(); + Codeunit.Run(Codeunit::"CA Posted Exp. Report"); + + UnbindSubscription(CAPostedExpReport); + end; +} diff --git a/src/Apps/W1/ExpenseAgent/demo data/Country/CA/CAExpCategories.Codeunit.al b/src/Apps/W1/ExpenseAgent/demo data/Country/CA/CAExpCategories.Codeunit.al new file mode 100644 index 00000000000..7509f594143 --- /dev/null +++ b/src/Apps/W1/ExpenseAgent/demo data/Country/CA/CAExpCategories.Codeunit.al @@ -0,0 +1,31 @@ +// ------------------------------------------------------------------------------------------------ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. See License.txt in the project root for license information. +// ------------------------------------------------------------------------------------------------ +namespace Microsoft.ExpenseAgent; + +codeunit 8249 "CA Exp. Categories" +{ + InherentEntitlements = X; + InherentPermissions = X; + + trigger OnRun() + var + CreateExpenseGroup: Codeunit "Create Expense Group"; + CreateExpensePaymentMethod: Codeunit "Create Expense Payment Method"; + ContosoExpenseAgent: Codeunit "Contoso Expense Agent"; + CAExpPostingGrp: Codeunit "CA Exp. Posting Grp"; + begin + ContosoExpenseAgent.InsertExpenseCategory(PerDiem(), PerDiemByAssignedPolicyLbl, PerDiemByAssignedPolicyPostingLbl, CAExpPostingGrp.ExpensePerDiem(), Enum::"Expense Attachment Enforcement"::" ", CreateExpensePaymentMethod.Cash(), false, false, CreateExpenseGroup.Travel(), true, Enum::"Expense Reimbursement Type"::"Employee Paid", Enum::"Expense Detail Needed"::"Per Diem"); + end; + + var + PerDiemTok: Label 'PER-DIEM', MaxLength = 20, Locked = true; + PerDiemByAssignedPolicyLbl: Label 'Expenses for per-diem or daily allowance paid for business trips, typically based on travel itinerary or other proof of travel (e.g., booking or agenda), rather than individual expense receipts.', MaxLength = 250; + PerDiemByAssignedPolicyPostingLbl: Label 'Per-diem by assigned policy', MaxLength = 100; + + procedure PerDiem(): Code[20] + begin + exit(PerDiemTok); + end; +} diff --git a/src/Apps/W1/ExpenseAgent/demo data/Country/CA/CAExpGLAccount.Codeunit.al b/src/Apps/W1/ExpenseAgent/demo data/Country/CA/CAExpGLAccount.Codeunit.al new file mode 100644 index 00000000000..a2019bf208b --- /dev/null +++ b/src/Apps/W1/ExpenseAgent/demo data/Country/CA/CAExpGLAccount.Codeunit.al @@ -0,0 +1,64 @@ +// ------------------------------------------------------------------------------------------------ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. See License.txt in the project root for license information. +// ------------------------------------------------------------------------------------------------ +namespace Microsoft.ExpenseAgent; + +using Microsoft.DemoTool.Helpers; +using Microsoft.Finance.GeneralLedger.Account; +using Microsoft.Foundation.Enums; + +codeunit 8246 "CA Exp. GL Account" +{ + SingleInstance = true; + EventSubscriberInstance = Manual; + InherentEntitlements = X; + InherentPermissions = X; + + [EventSubscriber(ObjectType::Codeunit, Codeunit::"Create Expense G/L Account", 'OnAfterAddGLAccountsForLocalization', '', false, false)] + local procedure ModifyGLAccount() + var + GLAccountCategory: Record "G/L Account Category"; + SubCategory: Text[80]; + begin + AddGLAccounts(); + + SubCategory := Format(GLAccountCategory."Account Category"::Assets, 80); + ContosoGLAccount.InsertGLAccount(ExpenseGLAccount.CompanyCreditCardsAccount(), ExpenseGLAccount.CompanyCreditCardsAccountName(), "G/L Account Income/Balance"::"Balance Sheet", Enum::"G/L Account Category"::Assets, SubCategory, Enum::"G/L Account Type"::Posting, '', '', '', 0, '', Enum::"General Posting Type"::" ", '', '', true, false, false); + ContosoGLAccount.InsertGLAccount(ExpenseGLAccount.EmployeePrepaymentsAccount(), ExpenseGLAccount.EmployeePrepaymentsAccountName(), "G/L Account Income/Balance"::"Balance Sheet", Enum::"G/L Account Category"::Assets, SubCategory, Enum::"G/L Account Type"::"Begin-Total", '', '', '', 0, '', Enum::"General Posting Type"::" ", '', '', false, false, false); + ContosoGLAccount.InsertGLAccount(ExpenseGLAccount.EmployeePrepaymentsExpensesAccount(), ExpenseGLAccount.EmployeePrepaymentsExpensesAccountName(), "G/L Account Income/Balance"::"Balance Sheet", Enum::"G/L Account Category"::Assets, SubCategory, Enum::"G/L Account Type"::Posting, '', '', '', 0, '', Enum::"General Posting Type"::" ", '', '', true, false, false); + ContosoGLAccount.InsertGLAccount(ExpenseGLAccount.EmployeePrepaymentsTotalAccount(), ExpenseGLAccount.EmployeePrepaymentsTotalAccountName(), "G/L Account Income/Balance"::"Balance Sheet", Enum::"G/L Account Category"::Assets, SubCategory, Enum::"G/L Account Type"::"End-Total", '', '', '', 0, ExpenseGLAccount.EmployeePrepaymentsAccount() + '..' + ExpenseGLAccount.EmployeePrepaymentsTotalAccount(), Enum::"General Posting Type"::" ", '', '', false, false, false); + + SubCategory := Format(GLAccountCategory."Account Category"::Expense, 80); + ContosoGLAccount.InsertGLAccount(ExpenseGLAccount.PerDiemTravelExpensesAccount(), ExpenseGLAccount.PerDiemTravelExpensesAccountName(), "G/L Account Income/Balance"::"Income Statement", Enum::"G/L Account Category"::Expense, SubCategory, Enum::"G/L Account Type"::Posting, '', '', '', 0, '', Enum::"General Posting Type"::Purchase, '', '', true, false, false); + ContosoGLAccount.InsertGLAccount(ExpenseGLAccount.MileageTravelExpensesAccount(), ExpenseGLAccount.MileageTravelExpensesAccountName(), "G/L Account Income/Balance"::"Income Statement", Enum::"G/L Account Category"::Expense, SubCategory, Enum::"G/L Account Type"::Posting, '', '', '', 0, '', Enum::"General Posting Type"::Purchase, '', '', true, false, false); + ContosoGLAccount.InsertGLAccount(ExpenseGLAccount.MealExpensesDeductibleAccount(), ExpenseGLAccount.MealExpensesDeductibleAccountName(), "G/L Account Income/Balance"::"Income Statement", Enum::"G/L Account Category"::Expense, SubCategory, Enum::"G/L Account Type"::Posting, '', '', '', 0, '', Enum::"General Posting Type"::Purchase, '', '', true, false, false); + ContosoGLAccount.InsertGLAccount(ExpenseGLAccount.MealExpensesNondeductibleAccount(), ExpenseGLAccount.MealExpensesNondeductibleAccountName(), "G/L Account Income/Balance"::"Income Statement", Enum::"G/L Account Category"::Expense, SubCategory, Enum::"G/L Account Type"::Posting, '', '', '', 0, '', Enum::"General Posting Type"::Purchase, '', '', true, false, false); + ContosoGLAccount.InsertGLAccount(ExpenseGLAccount.OtherNondeductibleTravelExpensesAccount(), ExpenseGLAccount.OtherNondeductibleTravelExpensesAccountName(), "G/L Account Income/Balance"::"Income Statement", Enum::"G/L Account Category"::Expense, SubCategory, Enum::"G/L Account Type"::Posting, '', '', '', 0, '', Enum::"General Posting Type"::Purchase, '', '', true, false, false); + ContosoGLAccount.InsertGLAccount(ExpenseGLAccount.MiscExternalExpensesNondeductibleAccount(), ExpenseGLAccount.MiscExternalExpensesNondeductibleAccountName(), "G/L Account Income/Balance"::"Income Statement", Enum::"G/L Account Category"::Expense, SubCategory, Enum::"G/L Account Type"::Posting, '', '', '', 0, '', Enum::"General Posting Type"::Purchase, '', '', true, false, false); + ContosoGLAccount.InsertGLAccount(ExpenseGLAccount.RentalVehiclesAccount(), ExpenseGLAccount.RentalVehiclesAccountName(), "G/L Account Income/Balance"::"Income Statement", Enum::"G/L Account Category"::Expense, SubCategory, Enum::"G/L Account Type"::Posting, '', '', '', 0, '', Enum::"General Posting Type"::Purchase, '', '', true, false, false); + ContosoGLAccount.InsertGLAccount(ExpenseGLAccount.BusinessEntertainingNondeductibleAccount(), ExpenseGLAccount.BusinessEntertainingNondeductibleAccountName(), "G/L Account Income/Balance"::"Income Statement", Enum::"G/L Account Category"::Expense, SubCategory, Enum::"G/L Account Type"::Posting, '', '', '', 0, '', Enum::"General Posting Type"::Purchase, '', '', true, false, false); + ContosoGLAccount.InsertGLAccount(ExpenseGLAccount.OtherTravelExpensesAccount(), ExpenseGLAccount.OtherTravelExpensesAccountName(), "G/L Account Income/Balance"::"Income Statement", Enum::"G/L Account Category"::Expense, SubCategory, Enum::"G/L Account Type"::Posting, '', '', '', 0, '', Enum::"General Posting Type"::Purchase, '', '', true, false, false); + end; + + local procedure AddGLAccounts() + begin + ContosoGLAccount.AddAccountForLocalization(ExpenseGLAccount.CompanyCreditCardsAccountName(), '11160'); + ContosoGLAccount.AddAccountForLocalization(ExpenseGLAccount.EmployeePrepaymentsAccountName(), '13600'); + ContosoGLAccount.AddAccountForLocalization(ExpenseGLAccount.EmployeePrepaymentsExpensesAccountName(), '13610'); + ContosoGLAccount.AddAccountForLocalization(ExpenseGLAccount.EmployeePrepaymentsTotalAccountName(), '13690'); + ContosoGLAccount.AddAccountForLocalization(ExpenseGLAccount.PerDiemTravelExpensesAccountName(), '61310'); + ContosoGLAccount.AddAccountForLocalization(ExpenseGLAccount.MileageTravelExpensesAccountName(), '61320'); + ContosoGLAccount.AddAccountForLocalization(ExpenseGLAccount.MealExpensesDeductibleAccountName(), '61330'); + ContosoGLAccount.AddAccountForLocalization(ExpenseGLAccount.MealExpensesNondeductibleAccountName(), '67410'); + ContosoGLAccount.AddAccountForLocalization(ExpenseGLAccount.OtherNondeductibleTravelExpensesAccountName(), '67420'); + ContosoGLAccount.AddAccountForLocalization(ExpenseGLAccount.MiscExternalExpensesNondeductibleAccountName(), '67430'); + ContosoGLAccount.AddAccountForLocalization(ExpenseGLAccount.RentalVehiclesAccountName(), '63110'); + ContosoGLAccount.AddAccountForLocalization(ExpenseGLAccount.BusinessEntertainingNondeductibleAccountName(), '61120'); + ContosoGLAccount.AddAccountForLocalization(ExpenseGLAccount.OtherTravelExpensesAccountName(), '61340'); + end; + + var + ContosoGLAccount: Codeunit "Contoso GL Account"; + ExpenseGLAccount: Codeunit "Create Expense G/L Account"; +} diff --git a/src/Apps/W1/ExpenseAgent/demo data/Country/CA/CAExpPostingGrp.Codeunit.al b/src/Apps/W1/ExpenseAgent/demo data/Country/CA/CAExpPostingGrp.Codeunit.al new file mode 100644 index 00000000000..09923dee6c9 --- /dev/null +++ b/src/Apps/W1/ExpenseAgent/demo data/Country/CA/CAExpPostingGrp.Codeunit.al @@ -0,0 +1,65 @@ +// ------------------------------------------------------------------------------------------------ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. See License.txt in the project root for license information. +// ------------------------------------------------------------------------------------------------ +namespace Microsoft.ExpenseAgent; + +using Microsoft.DemoData.Finance; + +codeunit 8247 "CA Exp. Posting Grp" +{ + SingleInstance = true; + EventSubscriberInstance = Manual; + InherentEntitlements = X; + InherentPermissions = X; + + trigger OnRun() + var + ContosoExpenseAgent: Codeunit "Contoso Expense Agent"; + begin + ContosoExpenseAgent.InsertExpensePostingGroup(ExpensePerDiem(), ExpensePerDiemLbl); + end; + + [EventSubscriber(ObjectType::Table, Database::"Expense Posting Group", 'OnBeforeInsertEvent', '', false, false)] + local procedure OnInsertRecord(var Rec: Record "Expense Posting Group") + var + CreateGLAccount: Codeunit "Create G/L Account"; + ExpenseGLAccount: Codeunit "Create Expense G/L Account"; + CreateExpensePostingGroup: Codeunit "Create Expense Posting Group"; + begin + case Rec.Code of + CreateExpensePostingGroup.ExpenseEntertainment(): + ValidateRecordFields(Rec, ExpenseGLAccount.FindGLAccountByName(CreateGLAccount.EntertainmentandPRName()), ExpenseGLAccount.FindGLAccountByName(CreateGLAccount.FinanceChargestoVendorsName()), ExpenseGLAccount.EmployeePrepaymentsExpensesAccount(), ExpenseGLAccount.FindGLAccountByName(CreateGLAccount.InvoiceRoundingName()), ExpenseGLAccount.FindGLAccountByName(CreateGLAccount.InvoiceRoundingName())); + CreateExpensePostingGroup.ExpenseMeals(): + ValidateRecordFields(Rec, ExpenseGLAccount.MealExpensesDeductibleAccount(), ExpenseGLAccount.FindGLAccountByName(CreateGLAccount.FinanceChargestoVendorsName()), ExpenseGLAccount.EmployeePrepaymentsExpensesAccount(), ExpenseGLAccount.FindGLAccountByName(CreateGLAccount.InvoiceRoundingName()), ExpenseGLAccount.FindGLAccountByName(CreateGLAccount.InvoiceRoundingName())); + CreateExpensePostingGroup.ExpenseMileage(): + ValidateRecordFields(Rec, ExpenseGLAccount.MileageTravelExpensesAccount(), '', ExpenseGLAccount.EmployeePrepaymentsExpensesAccount(), ExpenseGLAccount.FindGLAccountByName(CreateGLAccount.InvoiceRoundingName()), ExpenseGLAccount.FindGLAccountByName(CreateGLAccount.InvoiceRoundingName())); + CreateExpensePostingGroup.ExpenseOther(): + ValidateRecordFields(Rec, ExpenseGLAccount.MiscExternalExpensesNondeductibleAccount(), ExpenseGLAccount.FindGLAccountByName(CreateGLAccount.FinanceChargestoVendorsName()), ExpenseGLAccount.EmployeePrepaymentsExpensesAccount(), ExpenseGLAccount.FindGLAccountByName(CreateGLAccount.InvoiceRoundingName()), ExpenseGLAccount.FindGLAccountByName(CreateGLAccount.InvoiceRoundingName())); + ExpensePerDiem(): + ValidateRecordFields(Rec, ExpenseGLAccount.PerDiemTravelExpensesAccount(), '', ExpenseGLAccount.EmployeePrepaymentsExpensesAccount(), ExpenseGLAccount.FindGLAccountByName(CreateGLAccount.InvoiceRoundingName()), ExpenseGLAccount.FindGLAccountByName(CreateGLAccount.InvoiceRoundingName())); + CreateExpensePostingGroup.ExpenseTravel(): + ValidateRecordFields(Rec, ExpenseGLAccount.OtherTravelExpensesAccount(), ExpenseGLAccount.FindGLAccountByName(CreateGLAccount.FinanceChargestoVendorsName()), ExpenseGLAccount.EmployeePrepaymentsExpensesAccount(), ExpenseGLAccount.FindGLAccountByName(CreateGLAccount.InvoiceRoundingName()), ExpenseGLAccount.FindGLAccountByName(CreateGLAccount.InvoiceRoundingName())); + CreateExpensePostingGroup.ExpenseRentalCars(): + ValidateRecordFields(Rec, ExpenseGLAccount.RentalVehiclesAccount(), ExpenseGLAccount.FindGLAccountByName(CreateGLAccount.FinanceChargestoVendorsName()), ExpenseGLAccount.EmployeePrepaymentsExpensesAccount(), ExpenseGLAccount.FindGLAccountByName(CreateGLAccount.InvoiceRoundingName()), ExpenseGLAccount.FindGLAccountByName(CreateGLAccount.InvoiceRoundingName())); + end; + end; + + local procedure ValidateRecordFields(var ExpensePostingGroup: Record "Expense Posting Group"; RefundableDebitAccount: Code[20]; NonRefundableDebitAccount: Code[20]; PrepaymentCreditAccount: Code[20]; ExpenseDebitRoundingAccount: Code[20]; ExpenseCreditRoundingAccount: Code[20]) + begin + ExpensePostingGroup.Validate("Refundable Debit Account", RefundableDebitAccount); + ExpensePostingGroup.Validate("Non-Refundable Debit Account", NonRefundableDebitAccount); + ExpensePostingGroup.Validate("Prepayment Credit Account", PrepaymentCreditAccount); + ExpensePostingGroup.Validate("Debit Rounding Account", ExpenseDebitRoundingAccount); + ExpensePostingGroup.Validate("Credit Rounding Account", ExpenseCreditRoundingAccount); + end; + + var + ExpensePERDIEMTok: Label 'EXPENSE-PERDIEM', MaxLength = 20, Locked = true; + ExpensePerDiemLbl: Label 'Expense - Per Diem', MaxLength = 100; + + procedure ExpensePerDiem(): Code[20] + begin + exit(ExpensePERDIEMTok); + end; +} diff --git a/src/Apps/W1/ExpenseAgent/demo data/Country/CA/CAExpRuleCondition.Codeunit.al b/src/Apps/W1/ExpenseAgent/demo data/Country/CA/CAExpRuleCondition.Codeunit.al new file mode 100644 index 00000000000..a0148255636 --- /dev/null +++ b/src/Apps/W1/ExpenseAgent/demo data/Country/CA/CAExpRuleCondition.Codeunit.al @@ -0,0 +1,26 @@ +// ------------------------------------------------------------------------------------------------ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. See License.txt in the project root for license information. +// ------------------------------------------------------------------------------------------------ +namespace Microsoft.ExpenseAgent; + +codeunit 8252 "CA Exp. Rule Condition" +{ + InherentEntitlements = X; + InherentPermissions = X; + + trigger OnRun() + var + CAExpCategories: Codeunit "CA Exp. Categories"; + CreateExpenseLocation: Codeunit "Create Expense Location"; + ContosoExpenseAgent: Codeunit "Contoso Expense Agent"; + begin + ContosoExpenseAgent.InsertExpenseRuleCondition(CAExpCategories.PerDiem(), CreateExpenseLocation.CanadaAll(), 0D, 10000, Enum::"Expense Rule Condition Type"::"Daily Rate", 125); + ContosoExpenseAgent.InsertExpenseRuleCondition(CAExpCategories.PerDiem(), CreateExpenseLocation.DenmarkAll(), 0D, 10000, Enum::"Expense Rule Condition Type"::"Daily Rate", 450); + ContosoExpenseAgent.InsertExpenseRuleCondition(CAExpCategories.PerDiem(), CreateExpenseLocation.Domestic(), 0D, 10000, Enum::"Expense Rule Condition Type"::"Daily Rate", 50); + ContosoExpenseAgent.InsertExpenseRuleCondition(CAExpCategories.PerDiem(), CreateExpenseLocation.FranceAll(), 0D, 10000, Enum::"Expense Rule Condition Type"::"Daily Rate", 110); + ContosoExpenseAgent.InsertExpenseRuleCondition(CAExpCategories.PerDiem(), CreateExpenseLocation.GermanyAll(), 0D, 10000, Enum::"Expense Rule Condition Type"::"Daily Rate", 105); + ContosoExpenseAgent.InsertExpenseRuleCondition(CAExpCategories.PerDiem(), CreateExpenseLocation.UKOther(), 0D, 10000, Enum::"Expense Rule Condition Type"::"Daily Rate", 115); + ContosoExpenseAgent.InsertExpenseRuleCondition(CAExpCategories.PerDiem(), CreateExpenseLocation.USAOther(), 0D, 10000, Enum::"Expense Rule Condition Type"::"Daily Rate", 120); + end; +} diff --git a/src/Apps/W1/ExpenseAgent/demo data/Country/CA/CAExpRuleHeader.Codeunit.al b/src/Apps/W1/ExpenseAgent/demo data/Country/CA/CAExpRuleHeader.Codeunit.al new file mode 100644 index 00000000000..8161f920459 --- /dev/null +++ b/src/Apps/W1/ExpenseAgent/demo data/Country/CA/CAExpRuleHeader.Codeunit.al @@ -0,0 +1,29 @@ +// ------------------------------------------------------------------------------------------------ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. See License.txt in the project root for license information. +// ------------------------------------------------------------------------------------------------ +namespace Microsoft.ExpenseAgent; + +using Microsoft.DemoData.Finance; + +codeunit 8251 "CA Exp. Rule Header" +{ + InherentEntitlements = X; + InherentPermissions = X; + + trigger OnRun() + var + CreateCurrency: Codeunit "Create Currency"; + CAExpCategories: Codeunit "CA Exp. Categories"; + CreateExpenseLocation: Codeunit "Create Expense Location"; + ContosoExpenseAgent: Codeunit "Contoso Expense Agent"; + begin + ContosoExpenseAgent.InsertExpenseRuleHeader(CAExpCategories.PerDiem(), CreateExpenseLocation.CanadaAll(), 0D, Enum::"Expense Justification"::" ", false, '', '', ''); + ContosoExpenseAgent.InsertExpenseRuleHeader(CAExpCategories.PerDiem(), CreateExpenseLocation.DenmarkAll(), 0D, Enum::"Expense Justification"::" ", false, '', CreateCurrency.EUR(), ''); + ContosoExpenseAgent.InsertExpenseRuleHeader(CAExpCategories.PerDiem(), CreateExpenseLocation.Domestic(), 0D, Enum::"Expense Justification"::" ", false, '', '', ''); + ContosoExpenseAgent.InsertExpenseRuleHeader(CAExpCategories.PerDiem(), CreateExpenseLocation.FranceAll(), 0D, Enum::"Expense Justification"::" ", false, '', CreateCurrency.EUR(), ''); + ContosoExpenseAgent.InsertExpenseRuleHeader(CAExpCategories.PerDiem(), CreateExpenseLocation.GermanyAll(), 0D, Enum::"Expense Justification"::" ", false, '', CreateCurrency.EUR(), ''); + ContosoExpenseAgent.InsertExpenseRuleHeader(CAExpCategories.PerDiem(), CreateExpenseLocation.UKOther(), 0D, Enum::"Expense Justification"::" ", false, '', CreateCurrency.GBP(), ''); + ContosoExpenseAgent.InsertExpenseRuleHeader(CAExpCategories.PerDiem(), CreateExpenseLocation.USAOther(), 0D, Enum::"Expense Justification"::" ", false, '', '', ''); + end; +} diff --git a/src/Apps/W1/ExpenseAgent/demo data/Country/CA/CAExpSubCategories.Codeunit.al b/src/Apps/W1/ExpenseAgent/demo data/Country/CA/CAExpSubCategories.Codeunit.al new file mode 100644 index 00000000000..3cea8233897 --- /dev/null +++ b/src/Apps/W1/ExpenseAgent/demo data/Country/CA/CAExpSubCategories.Codeunit.al @@ -0,0 +1,39 @@ +// ------------------------------------------------------------------------------------------------ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. See License.txt in the project root for license information. +// ------------------------------------------------------------------------------------------------ +namespace Microsoft.ExpenseAgent; + +codeunit 8250 "CA Exp. SubCategories" +{ + InherentEntitlements = X; + InherentPermissions = X; + + trigger OnRun() + var + ContosoExpenseAgent: Codeunit "Contoso Expense Agent"; + CAExpCategories: Codeunit "CA Exp. Categories"; + begin + // PER-DIEM subcategories + ContosoExpenseAgent.InsertExpenseSubcategory(Country(), CAExpCategories.PerDiem(), LocalCountryPerDiemLbl, LocalCountryPerDiemPostingLbl, false, true, false); + ContosoExpenseAgent.InsertExpenseSubcategory(Intl(), CAExpCategories.PerDiem(), InternationalPerDiemLbl, InternationalPerDiemPostingLbl, false, true, false); + end; + + var + CountryTok: Label 'COUNTRY', MaxLength = 20, Locked = true; + IntlTok: Label 'INTL', MaxLength = 20, Locked = true; + LocalCountryPerDiemLbl: Label 'Daily per-diem allowance based on domestic travel rates, paid instead of individual meal or incidental expense reimbursements.', MaxLength = 250; + InternationalPerDiemLbl: Label 'Daily per-diem allowance for international business travel, based on applicable foreign travel rates.', MaxLength = 250; + LocalCountryPerDiemPostingLbl: Label 'Local country per-diem', MaxLength = 100; + InternationalPerDiemPostingLbl: Label 'International per-diem', MaxLength = 100; + + procedure Country(): Code[20] + begin + exit(CountryTok); + end; + + procedure Intl(): Code[20] + begin + exit(IntlTok); + end; +} diff --git a/src/Apps/W1/ExpenseAgent/demo data/Country/CA/CAExpense.Codeunit.al b/src/Apps/W1/ExpenseAgent/demo data/Country/CA/CAExpense.Codeunit.al new file mode 100644 index 00000000000..5c66e613c53 --- /dev/null +++ b/src/Apps/W1/ExpenseAgent/demo data/Country/CA/CAExpense.Codeunit.al @@ -0,0 +1,51 @@ +// ------------------------------------------------------------------------------------------------ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. See License.txt in the project root for license information. +// ------------------------------------------------------------------------------------------------ +namespace Microsoft.ExpenseAgent; + +using Microsoft.DemoTool.Helpers; + +codeunit 8253 "CA Expense" +{ + InherentEntitlements = X; + InherentPermissions = X; + Permissions = tabledata "Expense Per Diem" = rim; + + trigger OnRun() + begin + CreateOpenExpense(); + end; + + local procedure CreateOpenExpense() + var + Expense: Record Expense; + ContosoExpenseAgent: Codeunit "Contoso Expense Agent"; + CreateExpenseLocation: Codeunit "Create Expense Location"; + begin + Expense := ContosoExpenseAgent.InsertExpense(CreateExpenseUser.EH(), CAExpCategories.PerDiem(), CreateExpenseLocation.DenmarkAll(), PerDiemByAssignedPolicyLbl, '', ContosoUtility.AdjustDate(19030203D), '', 0, '', CreateExpensePaymentMethod.Cash(), true, false, '', CreateDateTime(ContosoUtility.AdjustDate(19030115D), 144000T), CreateDateTime(ContosoUtility.AdjustDate(19030121D), 000500T), 0, 0, '', '', '', '', ''); + UpdateExpensePerDiem(Expense."No.", 10000, false, false, true); + UpdateExpensePerDiem(Expense."No.", 30000, false, true, false); + UpdateExpensePerDiem(Expense."No.", 40000, false, false, true); + UpdateExpensePerDiem(Expense."No.", 60000, false, true, true); + end; + + var + ContosoUtility: Codeunit "Contoso Utilities"; + CreateExpenseUser: Codeunit "Create Expense User"; + CAExpCategories: Codeunit "CA Exp. Categories"; + CreateExpensePaymentMethod: Codeunit "Create Expense Payment Method"; + PerDiemByAssignedPolicyLbl: Label 'Per-diem by assigned policy', MaxLength = 100; + + local procedure UpdateExpensePerDiem(ExpenseNo: Code[20]; LineNo: Integer; Breakfast: Boolean; Lunch: Boolean; Dinner: Boolean) + var + ExpensePerDiem: Record "Expense Per Diem"; + begin + ExpensePerDiem.Get(ExpenseNo, LineNo); + + ExpensePerDiem.Validate(Breakfast, Breakfast); + ExpensePerDiem.Validate(Lunch, Lunch); + ExpensePerDiem.Validate(Dinner, Dinner); + ExpensePerDiem.Modify(); + end; +} diff --git a/src/Apps/W1/ExpenseAgent/demo data/Country/CA/CAPostedExpReport.Codeunit.al b/src/Apps/W1/ExpenseAgent/demo data/Country/CA/CAPostedExpReport.Codeunit.al new file mode 100644 index 00000000000..7ee1e98d313 --- /dev/null +++ b/src/Apps/W1/ExpenseAgent/demo data/Country/CA/CAPostedExpReport.Codeunit.al @@ -0,0 +1,168 @@ +// ------------------------------------------------------------------------------------------------ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. See License.txt in the project root for license information. +// ------------------------------------------------------------------------------------------------ +namespace Microsoft.ExpenseAgent; + +using Microsoft.DemoData.Finance; +using Microsoft.DemoData.HumanResources; +using Microsoft.DemoTool.Helpers; + +codeunit 8254 "CA Posted Exp. Report" +{ + SingleInstance = true; + EventSubscriberInstance = Manual; + InherentEntitlements = X; + InherentPermissions = X; + Permissions = + tabledata "Expense Per Diem" = rim, + tabledata "Expense Report Line" = rim; + + trigger OnRun() + var + ExpenseReportHeader: Record "Expense Report Header"; + begin + if ExpenseReportHeader.FindLast() then + FromExpenseReportNo := ExpenseReportHeader."No."; + + CreateExpenseReportToPost(); + + PostExpenseReport(); + end; + + [EventSubscriber(ObjectType::Codeunit, Codeunit::"Create Posted Expense Report", OnDefineExpenseAccountNo, '', false, false)] + local procedure OnDefineExpenseAccountNo(var AccountNo: Code[20]) + var + CreateGLAccount: Codeunit "Create G/L Account"; + ExpenseGLAccount: Codeunit "Create Expense G/L Account"; + begin + AccountNo := ExpenseGLAccount.FindGLAccountByName(CreateGLAccount.SalesResourcesExportName()); + end; + + local procedure CreateExpenseReportToPost() + var + Expense: Record Expense; + ExpenseReportHeader: Record "Expense Report Header"; + CreateEmployee: Codeunit "Create Employee"; + CreateCurrency: Codeunit "Create Currency"; + ContosoUtility: Codeunit "Contoso Utilities"; + CreateExpenseUser: Codeunit "Create Expense User"; + CreateExpenseLocation: Codeunit "Create Expense Location"; + ContosoExpenseAgent: Codeunit "Contoso Expense Agent"; + CreateExpCategories: Codeunit "Create Expense Categories DM"; + CAExpCategories: Codeunit "CA Exp. Categories"; + CreateExpenseSubcategories: Codeunit "Create Expense Subcategories"; + CreateExpensePaymentMethod: Codeunit "Create Expense Payment Method"; + begin + ExpenseReportHeader := ContosoExpenseAgent.InsertExpenseReportHeader(CreateExpenseUser.JO(), ContosoUtility.AdjustDate(19021104D), ContosoUtility.AdjustDate(19021104D)); + Expense := ContosoExpenseAgent.InsertExpense(CreateExpenseUser.JO(), CAExpCategories.PerDiem(), CreateExpenseLocation.GermanyAll(), BusinessTripToHamburgLbl, '', ContosoUtility.AdjustDate(19021103D), '', 0, '', CreateExpensePaymentMethod.Cash(), true, false, '', CreateDateTime(ContosoUtility.AdjustDate(19021024D), 064500T), CreateDateTime(ContosoUtility.AdjustDate(19021027D), 161500T), 0, 0, '', '', '', '', ''); + ReleaseAndAddExpenseToExpenseReport(Expense, ExpenseReportHeader); + Expense := ContosoExpenseAgent.InsertExpense(CreateExpenseUser.JO(), CreateExpCategories.Airline(), '', AirlineTicketsLbl, '', ContosoUtility.AdjustDate(19021010D), '', 2042, MargieTravelLbl, CreateExpensePaymentMethod.Card(), true, false, '', 0DT, 0DT, 0, 0, '', '', 'TY6HJO', '', ''); + ReleaseAndAddExpenseToExpenseReport(Expense, ExpenseReportHeader); + + ExpenseReportHeader := ContosoExpenseAgent.InsertExpenseReportHeader(CreateExpenseUser.EH(), ContosoUtility.AdjustDate(19021204D), ContosoUtility.AdjustDate(19021204D)); + Expense := ContosoExpenseAgent.InsertExpense(CreateExpenseUser.EH(), CreateExpCategories.Airline(), '', AirlineTicketsDublinLbl, TravelToConferenceLbl, ContosoUtility.AdjustDate(19021106D), '', 3120, MargieTravelLbl, CreateExpensePaymentMethod.Card(), true, false, '', 0DT, 0DT, 0, 0, '', '', 'FIUXHJT', '', ''); + ReleaseAndAddExpenseToExpenseReport(Expense, ExpenseReportHeader); + Expense := ContosoExpenseAgent.InsertExpense(CreateExpenseUser.EH(), CreateExpCategories.Events(), '', ITConferenceLbl, '', ContosoUtility.AdjustDate(19021107D), CreateCurrency.EUR(), 1990, ProsewareIncLbl, CreateExpensePaymentMethod.Card(), true, false, '', 0DT, 0DT, 0, 0, '', '', 'G574576HJ656', '', ''); + ReleaseAndAddExpenseToExpenseReport(Expense, ExpenseReportHeader); + Expense := ContosoExpenseAgent.InsertExpense(CreateExpenseUser.EH(), CreateExpCategories.GroundTransportation(), '', TaxiLbl, '', ContosoUtility.AdjustDate(19021114D), CreateCurrency.EUR(), 45, TailwindTradersLbl, CreateExpensePaymentMethod.Cash(), true, false, '', 0DT, 0DT, 0, 0, '', '', '456845856867', '', ''); + ReleaseAndAddExpenseToExpenseReport(Expense, ExpenseReportHeader); + Expense := ContosoExpenseAgent.InsertExpense(CreateExpenseUser.EH(), CreateExpCategories.Entertain(), '', BusinessDinnerLbl, BusinessDinnerWithBigPotentialCustomersLbl, ContosoUtility.AdjustDate(19021116D), CreateCurrency.EUR(), 842, FourthCoffeeLbl, CreateExpensePaymentMethod.Card(), true, false, '', 0DT, 0DT, 0, 0, '', '', 'RT6457560034', '', ''); + ContosoExpenseAgent.InsertExpenseParticipant(Expense."No.", 10000, CreateExpCategories.Entertain(), Enum::"Expense Participant Type"::Employee, CreateEmployee.ManagingDirector(), '', '', '', '', ''); + ContosoExpenseAgent.InsertExpenseParticipant(Expense."No.", 20000, CreateExpCategories.Entertain(), Enum::"Expense Participant Type"::Employee, CreateEmployee.SalesManager(), '', '', '', '', ''); + ContosoExpenseAgent.InsertExpenseParticipant(Expense."No.", 30000, CreateExpCategories.Entertain(), Enum::"Expense Participant Type"::External, '', JesseHomerLbl, RelecloudLbl, '', CEOLbl, 'jesse.homer@contoso.com'); + ContosoExpenseAgent.InsertExpenseParticipant(Expense."No.", 40000, CreateExpCategories.Entertain(), Enum::"Expense Participant Type"::External, '', RobertTownesLbl, AdatumCorporationLbl, '', CEOLbl, 'robert.townes@contoso.com'); + ReleaseAndAddExpenseToExpenseReport(Expense, ExpenseReportHeader); + Expense := ContosoExpenseAgent.InsertExpense(CreateExpenseUser.EH(), CreateExpCategories.Hotels(), '', HotelStayLbl, '', ContosoUtility.AdjustDate(19021118D), CreateCurrency.EUR(), 2150, ContosoSuitesLbl, CreateExpensePaymentMethod.Card(), true, false, '', 0DT, 0DT, 0, 0, '', '', '64675S879CT987990004', '', ''); + ContosoExpenseAgent.InsertExpenseItemization(Expense."No.", 10000, CreateExpCategories.Hotels(), CreateExpenseSubcategories.Room(), AccommodationLbl, ContosoUtility.AdjustDate(19021114D), 390); + ContosoExpenseAgent.InsertExpenseItemization(Expense."No.", 20000, CreateExpCategories.Hotels(), CreateExpenseSubcategories.Breakfast(), BreakfastLbl, ContosoUtility.AdjustDate(19021115D), 35); + ContosoExpenseAgent.InsertExpenseItemization(Expense."No.", 30000, CreateExpCategories.Hotels(), CreateExpenseSubcategories.Room(), AccommodationLbl, ContosoUtility.AdjustDate(19021115D), 390); + ContosoExpenseAgent.InsertExpenseItemization(Expense."No.", 40000, CreateExpCategories.Hotels(), CreateExpenseSubcategories.Breakfast(), BreakfastLbl, ContosoUtility.AdjustDate(19021116D), 35); + ContosoExpenseAgent.InsertExpenseItemization(Expense."No.", 50000, CreateExpCategories.Hotels(), CreateExpenseSubcategories.Room(), AccommodationLbl, ContosoUtility.AdjustDate(19021116D), 390); + ContosoExpenseAgent.InsertExpenseItemization(Expense."No.", 60000, CreateExpCategories.Hotels(), CreateExpenseSubcategories.RoomService(), RoomServiceLbl, ContosoUtility.AdjustDate(19021116D), 145); + ContosoExpenseAgent.InsertExpenseItemization(Expense."No.", 70000, CreateExpCategories.Hotels(), CreateExpenseSubcategories.Breakfast(), BreakfastLbl, ContosoUtility.AdjustDate(19021117D), 35); + ContosoExpenseAgent.InsertExpenseItemization(Expense."No.", 80000, CreateExpCategories.Hotels(), CreateExpenseSubcategories.Room(), AccommodationLbl, ContosoUtility.AdjustDate(19021117D), 390); + ContosoExpenseAgent.InsertExpenseItemization(Expense."No.", 90000, CreateExpCategories.Hotels(), CreateExpenseSubcategories.Breakfast(), BreakfastLbl, ContosoUtility.AdjustDate(19021118D), 35); + ContosoExpenseAgent.InsertExpenseItemization(Expense."No.", 100000, CreateExpCategories.Hotels(), CreateExpenseSubcategories.Tax(), HotelTaxesLbl, ContosoUtility.AdjustDate(19021118D), 305); + ReleaseAndAddExpenseToExpenseReport(Expense, ExpenseReportHeader); + Expense := ContosoExpenseAgent.InsertExpense(CreateExpenseUser.EH(), CreateExpCategories.RentalCars(), '', CarRentalsLbl, '', ContosoUtility.AdjustDate(19021118D), CreateCurrency.EUR(), 622.45, VanArsdelLtdLbl, CreateExpensePaymentMethod.Card(), true, false, '', 0DT, 0DT, 0, 0, '', '', 'H6584769867J9J95789', '', ''); + ReleaseAndAddExpenseToExpenseReport(Expense, ExpenseReportHeader); + Expense := ContosoExpenseAgent.InsertExpense(CreateExpenseUser.EH(), CreateExpCategories.GroundTransportation(), '', TaxiLbl, '', ContosoUtility.AdjustDate(19021118D), CreateCurrency.EUR(), 71, TailwindTradersLbl, CreateExpensePaymentMethod.Cash(), true, false, '', 0DT, 0DT, 0, 0, '', '', '7456875687568', '', ''); + ReleaseAndAddExpenseToExpenseReport(Expense, ExpenseReportHeader); + Expense := ContosoExpenseAgent.InsertExpense(CreateExpenseUser.EH(), CAExpCategories.PerDiem(), CreateExpenseLocation.UKOther(), TripToUKLbl, '', ContosoUtility.AdjustDate(19021121D), '', 0, '', CreateExpensePaymentMethod.Cash(), true, false, '', CreateDateTime(ContosoUtility.AdjustDate(19021114D), 053000T), CreateDateTime(ContosoUtility.AdjustDate(19021118D), 220500T), 0, 0, '', '', '', '', ''); + UpdateExpensePerDiem(Expense."No.", 20000, false, false, true); + UpdateExpensePerDiem(Expense."No.", 40000, false, true, false); + ReleaseAndAddExpenseToExpenseReport(Expense, ExpenseReportHeader); + Expense := ContosoExpenseAgent.InsertExpense(CreateExpenseUser.EH(), CAExpCategories.PerDiem(), CreateExpenseLocation.Domestic(), TripToDoverLbl, '', ContosoUtility.AdjustDate(19021204D), '', 0, '', CreateExpensePaymentMethod.Cash(), true, false, '', CreateDateTime(ContosoUtility.AdjustDate(19021127D), 070000T), CreateDateTime(ContosoUtility.AdjustDate(19021129D), 145500T), 0, 0, '', '', '', '', ''); + ReleaseAndAddExpenseToExpenseReport(Expense, ExpenseReportHeader); + Expense := ContosoExpenseAgent.InsertExpense(CreateExpenseUser.EH(), CreateExpCategories.Mileage(), '', MileageLbl, '', ContosoUtility.AdjustDate(19031101D), '', 0, VanArsdelLtdLbl, CreateExpensePaymentMethod.Cash(), true, false, '', 0DT, 0DT, 0, 249, 'New York', 'Dover', 'H6584769867J9J95789', '', ''); + ReleaseAndAddExpenseToExpenseReport(Expense, ExpenseReportHeader); + end; + + var + FromExpenseReportNo: Code[20]; + BusinessTripToHamburgLbl: Label 'Business trip to Hamburg, DE', MaxLength = 100; + AirlineTicketsLbl: Label 'Airline tickets NY/FRANKFURT/HAMBURG/FRANKFURT/NY', MaxLength = 100; + MargieTravelLbl: Label 'Margie''s Travel', MaxLength = 100; + AirlineTicketsDublinLbl: Label 'Airline tickets NY/DUBLIN/NY', MaxLength = 100; + TravelToConferenceLbl: Label 'Travel to the conference', MaxLength = 100; + ITConferenceLbl: Label 'IT Conference', MaxLength = 100; + ProsewareIncLbl: Label 'Proseware, Inc.', MaxLength = 100; + TaxiLbl: Label 'Taxi', MaxLength = 100; + TailwindTradersLbl: Label 'Tailwind Traders', MaxLength = 100; + BusinessDinnerLbl: Label 'Business Dinner', MaxLength = 100; + BusinessDinnerWithBigPotentialCustomersLbl: Label 'Business dinner with a big potential customers', MaxLength = 100; + FourthCoffeeLbl: Label 'Fourth Coffee', MaxLength = 100; + JesseHomerLbl: Label 'Jesse Homer', MaxLength = 100; + RelecloudLbl: Label 'Relecloud', MaxLength = 100; + RobertTownesLbl: Label 'Robert Townes', MaxLength = 100; + AdatumCorporationLbl: Label 'Adatum Corporation', MaxLength = 100; + HotelStayLbl: Label 'Hotel stay', MaxLength = 100; + ContosoSuitesLbl: Label 'Contoso Suites', MaxLength = 100; + AccommodationLbl: Label 'Accommodation', MaxLength = 100; + BreakfastLbl: Label 'Breakfast', MaxLength = 100; + HotelTaxesLbl: Label 'Hotel Taxes', MaxLength = 100; + RoomServiceLbl: Label 'Room service', MaxLength = 100; + CarRentalsLbl: Label 'Car Rentals', MaxLength = 100; + VanArsdelLtdLbl: Label 'VanArsdel, Ltd.', MaxLength = 100; + TripToUKLbl: Label 'Trip to UK', MaxLength = 100; + TripToDoverLbl: Label 'Trip to Dover', MaxLength = 100; + MileageLbl: Label 'Mileage', MaxLength = 100; + CEOLbl: Label 'CEO', MaxLength = 30; + + local procedure ReleaseAndAddExpenseToExpenseReport(Expense: Record Expense; ExpenseReportHeader: Record "Expense Report Header") + var + ReleaseExpenseDocument: Codeunit "Release Expense Document"; + CreateExpenseReport: Codeunit "Create Expense Report"; + begin + Expense.Get(Expense."No."); + ReleaseExpenseDocument.Run(Expense); + + CreateExpenseReport.AddSingleExpenseToExpenseReport(Expense, ExpenseReportHeader); + end; + + local procedure PostExpenseReport() + var + ExpenseReportHeader: Record "Expense Report Header"; + begin + if FromExpenseReportNo <> '' then + ExpenseReportHeader.SetFilter("No.", '>%1', FromExpenseReportNo); + + if ExpenseReportHeader.FindSet() then + repeat + Codeunit.Run(Codeunit::"Expense Report-Post", ExpenseReportHeader); + until ExpenseReportHeader.Next() = 0; + end; + + local procedure UpdateExpensePerDiem(ExpenseNo: Code[20]; LineNo: Integer; Breakfast: Boolean; Lunch: Boolean; Dinner: Boolean) + var + ExpensePerDiem: Record "Expense Per Diem"; + begin + ExpensePerDiem.Get(ExpenseNo, LineNo); + + ExpensePerDiem.Validate(Breakfast, Breakfast); + ExpensePerDiem.Validate(Lunch, Lunch); + ExpensePerDiem.Validate(Dinner, Dinner); + ExpensePerDiem.Modify(); + end; +} diff --git a/src/Apps/W1/ExpenseAgent/demo data/Country/CA/CAUpdEmpPostingGrp.Codeunit.al b/src/Apps/W1/ExpenseAgent/demo data/Country/CA/CAUpdEmpPostingGrp.Codeunit.al new file mode 100644 index 00000000000..68f4f3b3f3d --- /dev/null +++ b/src/Apps/W1/ExpenseAgent/demo data/Country/CA/CAUpdEmpPostingGrp.Codeunit.al @@ -0,0 +1,34 @@ +// ------------------------------------------------------------------------------------------------ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. See License.txt in the project root for license information. +// ------------------------------------------------------------------------------------------------ +namespace Microsoft.ExpenseAgent; + +using Microsoft.DemoData.Finance; +using Microsoft.DemoData.HumanResources; + +codeunit 8248 "CA Upd. Emp. Posting Grp" +{ + InherentEntitlements = X; + InherentPermissions = X; + + trigger OnRun() + begin + UpdateEmployeePostingGroup(); + end; + + local procedure UpdateEmployeePostingGroup() + var + CreateGLAccount: Codeunit "Create G/L Account"; + ExpenseGLAccount: Codeunit "Create Expense G/L Account"; + ContosoExpenseAgent: Codeunit "Contoso Expense Agent"; + CreateEmployeePostingGroup: Codeunit "Create Employee Posting Group"; + begin + ContosoExpenseAgent.SetOverwriteData(true); + ContosoExpenseAgent.UpdateEmployeePostingGroup(CreateEmployeePostingGroup.EmployeeExpenses(), ExpenseGLAccount.FindGLAccountByName(CreateGLAccount.VacationCompensationPayableName()), ExpenseGLAccount.EmployeePrepaymentsExpensesAccount(), ExpenseGLAccount.FindGLAccountByName(BankCheckingLbl), ExpenseGLAccount.CompanyCreditCardsAccount()); + ContosoExpenseAgent.SetOverwriteData(false); + end; + + var + BankCheckingLbl: Label 'Bank, Checking', MaxLength = 100; +} diff --git a/src/Apps/W1/ExpenseAgent/demo data/Country/DE/DECountryData.Codeunit.al b/src/Apps/W1/ExpenseAgent/demo data/Country/DE/DECountryData.Codeunit.al new file mode 100644 index 00000000000..cad89122b34 --- /dev/null +++ b/src/Apps/W1/ExpenseAgent/demo data/Country/DE/DECountryData.Codeunit.al @@ -0,0 +1,64 @@ +// ------------------------------------------------------------------------------------------------ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. See License.txt in the project root for license information. +// ------------------------------------------------------------------------------------------------ +namespace Microsoft.ExpenseAgent; + +codeunit 8311 "DE Country Data" implements "Expense Agent Country Data" +{ + Access = Internal; + InherentEntitlements = X; + InherentPermissions = X; + + procedure CreateSetupData() + var + W1CountryData: Codeunit "W1 Country Data"; + DEExpGLAccount: Codeunit "DE Exp. GL Account"; + DEExpPostingGrp: Codeunit "DE Exp. Posting Grp"; + begin + BindSubscription(DEExpGLAccount); + BindSubscription(DEExpPostingGrp); + + W1CountryData.CreateSetupData(); + Codeunit.Run(Codeunit::"DE Upd. Emp. Posting Grp"); + Codeunit.Run(Codeunit::"DE Exp. Posting Grp"); + + UnbindSubscription(DEExpPostingGrp); + UnbindSubscription(DEExpGLAccount); + end; + + procedure CreateMasterData() + var + W1CountryData: Codeunit "W1 Country Data"; + begin + W1CountryData.CreateMasterData(); + Codeunit.Run(Codeunit::"DE Exp. Categories"); + Codeunit.Run(Codeunit::"DE Exp. SubCategories"); + Codeunit.Run(Codeunit::"DE Exp. Rule Header"); + Codeunit.Run(Codeunit::"DE Exp. Rule Condition"); + end; + + procedure CreateTransactionalData() + var + W1CountryData: Codeunit "W1 Country Data"; + begin + W1CountryData.CreateTransactionalData(); + Codeunit.Run(Codeunit::"DE Expense"); + end; + + procedure CreateHistoricalData() + var + W1CountryData: Codeunit "W1 Country Data"; + DECurrencySwapSub: Codeunit "DE Currency Swap Sub"; + DEPostedExpReport: Codeunit "DE Posted Exp. Report"; + begin + BindSubscription(DECurrencySwapSub); + BindSubscription(DEPostedExpReport); + + W1CountryData.CreateHistoricalData(); + Codeunit.Run(Codeunit::"DE Posted Exp. Report"); + + UnbindSubscription(DEPostedExpReport); + UnbindSubscription(DECurrencySwapSub); + end; +} diff --git a/src/Apps/W1/ExpenseAgent/demo data/Country/DE/DECurrencySwapSub.Codeunit.al b/src/Apps/W1/ExpenseAgent/demo data/Country/DE/DECurrencySwapSub.Codeunit.al new file mode 100644 index 00000000000..71dc49cbd8b --- /dev/null +++ b/src/Apps/W1/ExpenseAgent/demo data/Country/DE/DECurrencySwapSub.Codeunit.al @@ -0,0 +1,24 @@ +// ------------------------------------------------------------------------------------------------ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. See License.txt in the project root for license information. +// ------------------------------------------------------------------------------------------------ +namespace Microsoft.ExpenseAgent; + +using Microsoft.DemoData.Finance; + +codeunit 8322 "DE Currency Swap Sub" +{ + SingleInstance = true; + EventSubscriberInstance = Manual; + InherentEntitlements = X; + InherentPermissions = X; + + [EventSubscriber(ObjectType::Codeunit, Codeunit::"Contoso Expense Agent", OnBeforeValidateCurrencyCodeInExpense, '', false, false)] + local procedure OnBeforeValidateCurrencyCodeInExpense(var CurrencyCode: Code[10]) + var + CreateCurrency: Codeunit "Create Currency"; + begin + if CurrencyCode = CreateCurrency.EUR() then + CurrencyCode := CreateCurrency.USD(); + end; +} diff --git a/src/Apps/W1/ExpenseAgent/demo data/Country/DE/DEExpCategories.Codeunit.al b/src/Apps/W1/ExpenseAgent/demo data/Country/DE/DEExpCategories.Codeunit.al new file mode 100644 index 00000000000..0c718c48e85 --- /dev/null +++ b/src/Apps/W1/ExpenseAgent/demo data/Country/DE/DEExpCategories.Codeunit.al @@ -0,0 +1,31 @@ +// ------------------------------------------------------------------------------------------------ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. See License.txt in the project root for license information. +// ------------------------------------------------------------------------------------------------ +namespace Microsoft.ExpenseAgent; + +codeunit 8316 "DE Exp. Categories" +{ + InherentEntitlements = X; + InherentPermissions = X; + + trigger OnRun() + var + CreateExpenseGroup: Codeunit "Create Expense Group"; + CreateExpensePaymentMethod: Codeunit "Create Expense Payment Method"; + ContosoExpenseAgent: Codeunit "Contoso Expense Agent"; + DEExpPostingGrp: Codeunit "DE Exp. Posting Grp"; + begin + ContosoExpenseAgent.InsertExpenseCategory(PerDiem(), PerDiemByAssignedPolicyLbl, PerDiemByAssignedPolicyPostingLbl, DEExpPostingGrp.ExpensePerDiem(), Enum::"Expense Attachment Enforcement"::" ", CreateExpensePaymentMethod.Cash(), false, false, CreateExpenseGroup.Travel(), true, Enum::"Expense Reimbursement Type"::"Employee Paid", Enum::"Expense Detail Needed"::"Per Diem"); + end; + + var + PerDiemTok: Label 'PER-DIEM', MaxLength = 20, Locked = true; + PerDiemByAssignedPolicyLbl: Label 'Expenses for per-diem or daily allowance paid for business trips, typically based on travel itinerary or other proof of travel (e.g., booking or agenda), rather than individual expense receipts.', MaxLength = 250; + PerDiemByAssignedPolicyPostingLbl: Label 'Per-diem by assigned policy', MaxLength = 100; + + procedure PerDiem(): Code[20] + begin + exit(PerDiemTok); + end; +} diff --git a/src/Apps/W1/ExpenseAgent/demo data/Country/DE/DEExpGLAccount.Codeunit.al b/src/Apps/W1/ExpenseAgent/demo data/Country/DE/DEExpGLAccount.Codeunit.al new file mode 100644 index 00000000000..add2d151b54 --- /dev/null +++ b/src/Apps/W1/ExpenseAgent/demo data/Country/DE/DEExpGLAccount.Codeunit.al @@ -0,0 +1,57 @@ +// ------------------------------------------------------------------------------------------------ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. See License.txt in the project root for license information. +// ------------------------------------------------------------------------------------------------ +namespace Microsoft.ExpenseAgent; + +using Microsoft.DemoTool.Helpers; +using Microsoft.Finance.GeneralLedger.Account; +using Microsoft.Foundation.Enums; + +codeunit 8313 "DE Exp. GL Account" +{ + SingleInstance = true; + EventSubscriberInstance = Manual; + InherentEntitlements = X; + InherentPermissions = X; + + [EventSubscriber(ObjectType::Codeunit, Codeunit::"Create Expense G/L Account", 'OnAfterAddGLAccountsForLocalization', '', false, false)] + local procedure ModifyGLAccount() + var + GLAccountCategory: Record "G/L Account Category"; + SubCategory: Text[80]; + begin + AddGLAccounts(); + + SubCategory := Format(GLAccountCategory."Account Category"::Assets, 80); + ContosoGLAccount.InsertGLAccount(CompanyCreditCardsClearingAccount(), CompanyCreditCardsClearingAccountName(), "G/L Account Income/Balance"::"Balance Sheet", Enum::"G/L Account Category"::Assets, SubCategory, Enum::"G/L Account Type"::Posting, '', '', '', 0, '', Enum::"General Posting Type"::" ", '', '', true, false, false); + + SubCategory := Format(GLAccountCategory."Account Category"::Expense, 80); + ContosoGLAccount.InsertGLAccount(ExpenseGLAccount.PerDiemTravelExpensesAccount(), ExpenseGLAccount.PerDiemTravelExpensesAccountName(), "G/L Account Income/Balance"::"Income Statement", Enum::"G/L Account Category"::Expense, SubCategory, Enum::"G/L Account Type"::Posting, '', '', '', 0, '', Enum::"General Posting Type"::Purchase, '', '', true, false, false); + ContosoGLAccount.InsertGLAccount(ExpenseGLAccount.MileageTravelExpensesAccount(), ExpenseGLAccount.MileageTravelExpensesAccountName(), "G/L Account Income/Balance"::"Income Statement", Enum::"G/L Account Category"::Expense, SubCategory, Enum::"G/L Account Type"::Posting, '', '', '', 0, '', Enum::"General Posting Type"::Purchase, '', '', true, false, false); + ContosoGLAccount.InsertGLAccount(ExpenseGLAccount.MealExpensesNondeductibleAccount(), ExpenseGLAccount.MealExpensesNondeductibleAccountName(), "G/L Account Income/Balance"::"Income Statement", Enum::"G/L Account Category"::Expense, SubCategory, Enum::"G/L Account Type"::Posting, '', '', '', 0, '', Enum::"General Posting Type"::Purchase, '', '', true, false, false); + end; + + local procedure AddGLAccounts() + begin + ContosoGLAccount.AddAccountForLocalization(CompanyCreditCardsClearingAccountName(), '3510'); + ContosoGLAccount.AddAccountForLocalization(ExpenseGLAccount.PerDiemTravelExpensesAccountName(), '6664'); + ContosoGLAccount.AddAccountForLocalization(ExpenseGLAccount.MileageTravelExpensesAccountName(), '6658'); + ContosoGLAccount.AddAccountForLocalization(ExpenseGLAccount.MealExpensesNondeductibleAccountName(), '6662'); + end; + + var + ContosoGLAccount: Codeunit "Contoso GL Account"; + ExpenseGLAccount: Codeunit "Create Expense G/L Account"; + CompanyCreditCardsClearingAccountTok: Label 'Company credit card clearing account', MaxLength = 100; + + procedure CompanyCreditCardsClearingAccount(): Code[20] + begin + exit(ContosoGLAccount.GetAccountNo(CompanyCreditCardsClearingAccountName())); + end; + + procedure CompanyCreditCardsClearingAccountName(): Text[100] + begin + exit(CompanyCreditCardsClearingAccountTok); + end; +} diff --git a/src/Apps/W1/ExpenseAgent/demo data/Country/DE/DEExpPostingGrp.Codeunit.al b/src/Apps/W1/ExpenseAgent/demo data/Country/DE/DEExpPostingGrp.Codeunit.al new file mode 100644 index 00000000000..1d0e86e0dd1 --- /dev/null +++ b/src/Apps/W1/ExpenseAgent/demo data/Country/DE/DEExpPostingGrp.Codeunit.al @@ -0,0 +1,63 @@ +// ------------------------------------------------------------------------------------------------ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. See License.txt in the project root for license information. +// ------------------------------------------------------------------------------------------------ +namespace Microsoft.ExpenseAgent; + +codeunit 8314 "DE Exp. Posting Grp" +{ + SingleInstance = true; + EventSubscriberInstance = Manual; + InherentEntitlements = X; + InherentPermissions = X; + + trigger OnRun() + var + ContosoExpenseAgent: Codeunit "Contoso Expense Agent"; + begin + ContosoExpenseAgent.InsertExpensePostingGroup(ExpensePerDiem(), ExpensePerDiemLbl); + end; + + [EventSubscriber(ObjectType::Table, Database::"Expense Posting Group", 'OnBeforeInsertEvent', '', false, false)] + local procedure OnInsertRecord(var Rec: Record "Expense Posting Group") + var + DEGLAccountNames: Codeunit "DE GL Account Names"; + ExpenseGLAccount: Codeunit "Create Expense G/L Account"; + CreateExpensePostingGroup: Codeunit "Create Expense Posting Group"; + begin + case Rec.Code of + CreateExpensePostingGroup.ExpenseEntertainment(): + ValidateRecordFields(Rec, ExpenseGLAccount.FindGLAccountByName(DEGLAccountNames.BusinessEntertainingdeductibleName()), '', ExpenseGLAccount.FindGLAccountByName(DEGLAccountNames.AssetsintheformofprepaidexpensesName()), ExpenseGLAccount.FindGLAccountByName(DEGLAccountNames.SalesInvoiceRoundingName()), ExpenseGLAccount.FindGLAccountByName(DEGLAccountNames.SalesInvoiceRoundingName())); + CreateExpensePostingGroup.ExpenseMeals(): + ValidateRecordFields(Rec, ExpenseGLAccount.FindGLAccountByName(DEGLAccountNames.BoardandlodgingName()), ExpenseGLAccount.MealExpensesNondeductibleAccount(), ExpenseGLAccount.FindGLAccountByName(DEGLAccountNames.AssetsintheformofprepaidexpensesName()), ExpenseGLAccount.FindGLAccountByName(DEGLAccountNames.SalesInvoiceRoundingName()), ExpenseGLAccount.FindGLAccountByName(DEGLAccountNames.SalesInvoiceRoundingName())); + CreateExpensePostingGroup.ExpenseMileage(): + ValidateRecordFields(Rec, ExpenseGLAccount.MileageTravelExpensesAccount(), '', ExpenseGLAccount.FindGLAccountByName(DEGLAccountNames.AssetsintheformofprepaidexpensesName()), ExpenseGLAccount.FindGLAccountByName(DEGLAccountNames.SalesInvoiceRoundingName()), ExpenseGLAccount.FindGLAccountByName(DEGLAccountNames.SalesInvoiceRoundingName())); + CreateExpensePostingGroup.ExpenseOther(): + ValidateRecordFields(Rec, ExpenseGLAccount.FindGLAccountByName(DEGLAccountNames.MiscexternalexpensesName()), ExpenseGLAccount.FindGLAccountByName(DEGLAccountNames.OthertravelexpensesName()), ExpenseGLAccount.FindGLAccountByName(DEGLAccountNames.AssetsintheformofprepaidexpensesName()), ExpenseGLAccount.FindGLAccountByName(DEGLAccountNames.SalesInvoiceRoundingName()), ExpenseGLAccount.FindGLAccountByName(DEGLAccountNames.SalesInvoiceRoundingName())); + ExpensePerDiem(): + ValidateRecordFields(Rec, ExpenseGLAccount.PerDiemTravelExpensesAccount(), '', ExpenseGLAccount.FindGLAccountByName(DEGLAccountNames.AssetsintheformofprepaidexpensesName()), ExpenseGLAccount.FindGLAccountByName(DEGLAccountNames.SalesInvoiceRoundingName()), ExpenseGLAccount.FindGLAccountByName(DEGLAccountNames.SalesInvoiceRoundingName())); + CreateExpensePostingGroup.ExpenseTravel(): + ValidateRecordFields(Rec, ExpenseGLAccount.FindGLAccountByName(DEGLAccountNames.OthertravelexpensesName()), ExpenseGLAccount.FindGLAccountByName(DEGLAccountNames.OthertravelexpensesName()), ExpenseGLAccount.FindGLAccountByName(DEGLAccountNames.AssetsintheformofprepaidexpensesName()), ExpenseGLAccount.FindGLAccountByName(DEGLAccountNames.SalesInvoiceRoundingName()), ExpenseGLAccount.FindGLAccountByName(DEGLAccountNames.SalesInvoiceRoundingName())); + CreateExpensePostingGroup.ExpenseRentalCars(): + ValidateRecordFields(Rec, ExpenseGLAccount.FindGLAccountByName(DEGLAccountNames.RentalvehiclesName()), '', ExpenseGLAccount.FindGLAccountByName(DEGLAccountNames.AssetsintheformofprepaidexpensesName()), ExpenseGLAccount.FindGLAccountByName(DEGLAccountNames.SalesInvoiceRoundingName()), ExpenseGLAccount.FindGLAccountByName(DEGLAccountNames.SalesInvoiceRoundingName())); + end; + end; + + local procedure ValidateRecordFields(var ExpensePostingGroup: Record "Expense Posting Group"; RefundableDebitAccount: Code[20]; NonRefundableDebitAccount: Code[20]; PrepaymentCreditAccount: Code[20]; ExpenseDebitRoundingAccount: Code[20]; ExpenseCreditRoundingAccount: Code[20]) + begin + ExpensePostingGroup.Validate("Refundable Debit Account", RefundableDebitAccount); + ExpensePostingGroup.Validate("Non-Refundable Debit Account", NonRefundableDebitAccount); + ExpensePostingGroup.Validate("Prepayment Credit Account", PrepaymentCreditAccount); + ExpensePostingGroup.Validate("Debit Rounding Account", ExpenseDebitRoundingAccount); + ExpensePostingGroup.Validate("Credit Rounding Account", ExpenseCreditRoundingAccount); + end; + + var + ExpensePERDIEMTok: Label 'EXPENSE-PERDIEM', MaxLength = 20, Locked = true; + ExpensePerDiemLbl: Label 'Expense - Per Diem', MaxLength = 100; + + procedure ExpensePerDiem(): Code[20] + begin + exit(ExpensePERDIEMTok); + end; +} diff --git a/src/Apps/W1/ExpenseAgent/demo data/Country/DE/DEExpRuleCondition.Codeunit.al b/src/Apps/W1/ExpenseAgent/demo data/Country/DE/DEExpRuleCondition.Codeunit.al new file mode 100644 index 00000000000..2468e6693c0 --- /dev/null +++ b/src/Apps/W1/ExpenseAgent/demo data/Country/DE/DEExpRuleCondition.Codeunit.al @@ -0,0 +1,26 @@ +// ------------------------------------------------------------------------------------------------ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. See License.txt in the project root for license information. +// ------------------------------------------------------------------------------------------------ +namespace Microsoft.ExpenseAgent; + +codeunit 8319 "DE Exp. Rule Condition" +{ + InherentEntitlements = X; + InherentPermissions = X; + + trigger OnRun() + var + DEExpCategories: Codeunit "DE Exp. Categories"; + CreateExpenseLocation: Codeunit "Create Expense Location"; + ContosoExpenseAgent: Codeunit "Contoso Expense Agent"; + begin + ContosoExpenseAgent.InsertExpenseRuleCondition(DEExpCategories.PerDiem(), CreateExpenseLocation.CanadaAll(), 0D, 10000, Enum::"Expense Rule Condition Type"::"Daily Rate", 125); + ContosoExpenseAgent.InsertExpenseRuleCondition(DEExpCategories.PerDiem(), CreateExpenseLocation.DenmarkAll(), 0D, 10000, Enum::"Expense Rule Condition Type"::"Daily Rate", 450); + ContosoExpenseAgent.InsertExpenseRuleCondition(DEExpCategories.PerDiem(), CreateExpenseLocation.Domestic(), 0D, 10000, Enum::"Expense Rule Condition Type"::"Daily Rate", 50); + ContosoExpenseAgent.InsertExpenseRuleCondition(DEExpCategories.PerDiem(), CreateExpenseLocation.FranceAll(), 0D, 10000, Enum::"Expense Rule Condition Type"::"Daily Rate", 110); + ContosoExpenseAgent.InsertExpenseRuleCondition(DEExpCategories.PerDiem(), CreateExpenseLocation.GermanyAll(), 0D, 10000, Enum::"Expense Rule Condition Type"::"Daily Rate", 105); + ContosoExpenseAgent.InsertExpenseRuleCondition(DEExpCategories.PerDiem(), CreateExpenseLocation.UKOther(), 0D, 10000, Enum::"Expense Rule Condition Type"::"Daily Rate", 115); + ContosoExpenseAgent.InsertExpenseRuleCondition(DEExpCategories.PerDiem(), CreateExpenseLocation.USAOther(), 0D, 10000, Enum::"Expense Rule Condition Type"::"Daily Rate", 120); + end; +} diff --git a/src/Apps/W1/ExpenseAgent/demo data/Country/DE/DEExpRuleHeader.Codeunit.al b/src/Apps/W1/ExpenseAgent/demo data/Country/DE/DEExpRuleHeader.Codeunit.al new file mode 100644 index 00000000000..7af023f38f8 --- /dev/null +++ b/src/Apps/W1/ExpenseAgent/demo data/Country/DE/DEExpRuleHeader.Codeunit.al @@ -0,0 +1,29 @@ +// ------------------------------------------------------------------------------------------------ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. See License.txt in the project root for license information. +// ------------------------------------------------------------------------------------------------ +namespace Microsoft.ExpenseAgent; + +using Microsoft.DemoData.Finance; + +codeunit 8318 "DE Exp. Rule Header" +{ + InherentEntitlements = X; + InherentPermissions = X; + + trigger OnRun() + var + CreateCurrency: Codeunit "Create Currency"; + DEExpCategories: Codeunit "DE Exp. Categories"; + CreateExpenseLocation: Codeunit "Create Expense Location"; + ContosoExpenseAgent: Codeunit "Contoso Expense Agent"; + begin + ContosoExpenseAgent.InsertExpenseRuleHeader(DEExpCategories.PerDiem(), CreateExpenseLocation.CanadaAll(), 0D, Enum::"Expense Justification"::" ", false, '', CreateCurrency.CAD(), ''); + ContosoExpenseAgent.InsertExpenseRuleHeader(DEExpCategories.PerDiem(), CreateExpenseLocation.DenmarkAll(), 0D, Enum::"Expense Justification"::" ", false, '', CreateCurrency.USD(), ''); + ContosoExpenseAgent.InsertExpenseRuleHeader(DEExpCategories.PerDiem(), CreateExpenseLocation.Domestic(), 0D, Enum::"Expense Justification"::" ", false, '', '', ''); + ContosoExpenseAgent.InsertExpenseRuleHeader(DEExpCategories.PerDiem(), CreateExpenseLocation.FranceAll(), 0D, Enum::"Expense Justification"::" ", false, '', CreateCurrency.USD(), ''); + ContosoExpenseAgent.InsertExpenseRuleHeader(DEExpCategories.PerDiem(), CreateExpenseLocation.GermanyAll(), 0D, Enum::"Expense Justification"::" ", false, '', CreateCurrency.USD(), ''); + ContosoExpenseAgent.InsertExpenseRuleHeader(DEExpCategories.PerDiem(), CreateExpenseLocation.UKOther(), 0D, Enum::"Expense Justification"::" ", false, '', CreateCurrency.GBP(), ''); + ContosoExpenseAgent.InsertExpenseRuleHeader(DEExpCategories.PerDiem(), CreateExpenseLocation.USAOther(), 0D, Enum::"Expense Justification"::" ", false, '', '', ''); + end; +} diff --git a/src/Apps/W1/ExpenseAgent/demo data/Country/DE/DEExpSubCategories.Codeunit.al b/src/Apps/W1/ExpenseAgent/demo data/Country/DE/DEExpSubCategories.Codeunit.al new file mode 100644 index 00000000000..03d3e292967 --- /dev/null +++ b/src/Apps/W1/ExpenseAgent/demo data/Country/DE/DEExpSubCategories.Codeunit.al @@ -0,0 +1,39 @@ +// ------------------------------------------------------------------------------------------------ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. See License.txt in the project root for license information. +// ------------------------------------------------------------------------------------------------ +namespace Microsoft.ExpenseAgent; + +codeunit 8317 "DE Exp. SubCategories" +{ + InherentEntitlements = X; + InherentPermissions = X; + + trigger OnRun() + var + ContosoExpenseAgent: Codeunit "Contoso Expense Agent"; + DEExpCategories: Codeunit "DE Exp. Categories"; + begin + // PER-DIEM subcategories + ContosoExpenseAgent.InsertExpenseSubcategory(Country(), DEExpCategories.PerDiem(), LocalCountryPerDiemLbl, LocalCountryPerDiemPostingLbl, false, true, false); + ContosoExpenseAgent.InsertExpenseSubcategory(Intl(), DEExpCategories.PerDiem(), InternationalPerDiemLbl, InternationalPerDiemPostingLbl, false, true, false); + end; + + var + CountryTok: Label 'COUNTRY', MaxLength = 20, Locked = true; + IntlTok: Label 'INTL', MaxLength = 20, Locked = true; + LocalCountryPerDiemLbl: Label 'Daily per-diem allowance based on domestic travel rates, paid instead of individual meal or incidental expense reimbursements.', MaxLength = 250; + InternationalPerDiemLbl: Label 'Daily per-diem allowance for international business travel, based on applicable foreign travel rates.', MaxLength = 250; + LocalCountryPerDiemPostingLbl: Label 'Local country per-diem', MaxLength = 100; + InternationalPerDiemPostingLbl: Label 'International per-diem', MaxLength = 100; + + procedure Country(): Code[20] + begin + exit(CountryTok); + end; + + procedure Intl(): Code[20] + begin + exit(IntlTok); + end; +} diff --git a/src/Apps/W1/ExpenseAgent/demo data/Country/DE/DEExpense.Codeunit.al b/src/Apps/W1/ExpenseAgent/demo data/Country/DE/DEExpense.Codeunit.al new file mode 100644 index 00000000000..99c1b2547a3 --- /dev/null +++ b/src/Apps/W1/ExpenseAgent/demo data/Country/DE/DEExpense.Codeunit.al @@ -0,0 +1,51 @@ +// ------------------------------------------------------------------------------------------------ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. See License.txt in the project root for license information. +// ------------------------------------------------------------------------------------------------ +namespace Microsoft.ExpenseAgent; + +using Microsoft.DemoTool.Helpers; + +codeunit 8320 "DE Expense" +{ + InherentEntitlements = X; + InherentPermissions = X; + Permissions = tabledata "Expense Per Diem" = rim; + + trigger OnRun() + begin + CreateOpenExpense(); + end; + + local procedure CreateOpenExpense() + var + Expense: Record Expense; + ContosoExpenseAgent: Codeunit "Contoso Expense Agent"; + CreateExpenseLocation: Codeunit "Create Expense Location"; + begin + Expense := ContosoExpenseAgent.InsertExpense(CreateExpenseUser.EH(), DEExpCategories.PerDiem(), CreateExpenseLocation.FranceAll(), PerDiemByAssignedPolicyLbl, '', ContosoUtility.AdjustDate(19030203D), '', 0, '', CreateExpensePaymentMethod.Cash(), true, false, '', CreateDateTime(ContosoUtility.AdjustDate(19030115D), 144000T), CreateDateTime(ContosoUtility.AdjustDate(19030121D), 000500T), 0, 0, '', '', '', '', ''); + UpdateExpensePerDiem(Expense."No.", 10000, false, false, true); + UpdateExpensePerDiem(Expense."No.", 30000, false, true, false); + UpdateExpensePerDiem(Expense."No.", 40000, false, false, true); + UpdateExpensePerDiem(Expense."No.", 60000, false, true, true); + end; + + var + ContosoUtility: Codeunit "Contoso Utilities"; + CreateExpenseUser: Codeunit "Create Expense User"; + DEExpCategories: Codeunit "DE Exp. Categories"; + CreateExpensePaymentMethod: Codeunit "Create Expense Payment Method"; + PerDiemByAssignedPolicyLbl: Label 'Per-diem by assigned policy', MaxLength = 100; + + local procedure UpdateExpensePerDiem(ExpenseNo: Code[20]; LineNo: Integer; Breakfast: Boolean; Lunch: Boolean; Dinner: Boolean) + var + ExpensePerDiem: Record "Expense Per Diem"; + begin + ExpensePerDiem.Get(ExpenseNo, LineNo); + + ExpensePerDiem.Validate(Breakfast, Breakfast); + ExpensePerDiem.Validate(Lunch, Lunch); + ExpensePerDiem.Validate(Dinner, Dinner); + ExpensePerDiem.Modify(); + end; +} diff --git a/src/Apps/W1/ExpenseAgent/demo data/Country/DE/DEGLAccountNames.Codeunit.al b/src/Apps/W1/ExpenseAgent/demo data/Country/DE/DEGLAccountNames.Codeunit.al new file mode 100644 index 00000000000..c5badd3457e --- /dev/null +++ b/src/Apps/W1/ExpenseAgent/demo data/Country/DE/DEGLAccountNames.Codeunit.al @@ -0,0 +1,68 @@ +// ------------------------------------------------------------------------------------------------ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. See License.txt in the project root for license information. +// ------------------------------------------------------------------------------------------------ +namespace Microsoft.ExpenseAgent; + +codeunit 8312 "DE GL Account Names" +{ + Access = Internal; + InherentEntitlements = X; + InherentPermissions = X; + + var + BusinessaccountOperatingDomesticTok: Label 'Business account, Operating, Domestic', MaxLength = 100; + SaleofResourcesTok: Label 'Sale of Resource', MaxLength = 100; + AssetsintheformofprepaidexpensesTok: Label 'Assets in the form of prepaid expenses', MaxLength = 100; + SalesInvoiceRoundingTok: Label 'Sales Invoice Rounding', MaxLength = 100; + BoardandlodgingTok: Label 'Board and lodging', MaxLength = 100; + MiscexternalexpensesTok: Label 'Misc. external expenses', MaxLength = 100; + OthertravelexpensesTok: Label 'Other travel expenses', MaxLength = 100; + RentalvehiclesTok: Label 'Rental vehicles', MaxLength = 100; + BusinessEntertainingdeductibleTok: Label 'Business Entertaining, deductible', MaxLength = 100; + + procedure BusinessaccountOperatingDomesticName(): Text[100] + begin + exit(BusinessaccountOperatingDomesticTok); + end; + + procedure SaleofResourcesName(): Text[100] + begin + exit(SaleofResourcesTok); + end; + + procedure AssetsintheformofprepaidexpensesName(): Text[100] + begin + exit(AssetsintheformofprepaidexpensesTok); + end; + + procedure SalesInvoiceRoundingName(): Text[100] + begin + exit(SalesInvoiceRoundingTok); + end; + + procedure BoardandlodgingName(): Text[100] + begin + exit(BoardandlodgingTok); + end; + + procedure MiscexternalexpensesName(): Text[100] + begin + exit(MiscexternalexpensesTok); + end; + + procedure OthertravelexpensesName(): Text[100] + begin + exit(OthertravelexpensesTok); + end; + + procedure RentalvehiclesName(): Text[100] + begin + exit(RentalvehiclesTok); + end; + + procedure BusinessEntertainingdeductibleName(): Text[100] + begin + exit(BusinessEntertainingdeductibleTok); + end; +} diff --git a/src/Apps/W1/ExpenseAgent/demo data/Country/DE/DEPostedExpReport.Codeunit.al b/src/Apps/W1/ExpenseAgent/demo data/Country/DE/DEPostedExpReport.Codeunit.al new file mode 100644 index 00000000000..356596ff253 --- /dev/null +++ b/src/Apps/W1/ExpenseAgent/demo data/Country/DE/DEPostedExpReport.Codeunit.al @@ -0,0 +1,168 @@ +// ------------------------------------------------------------------------------------------------ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. See License.txt in the project root for license information. +// ------------------------------------------------------------------------------------------------ +namespace Microsoft.ExpenseAgent; + +using Microsoft.DemoData.Finance; +using Microsoft.DemoData.HumanResources; +using Microsoft.DemoTool.Helpers; + +codeunit 8321 "DE Posted Exp. Report" +{ + SingleInstance = true; + EventSubscriberInstance = Manual; + InherentEntitlements = X; + InherentPermissions = X; + Permissions = + tabledata "Expense Per Diem" = rim, + tabledata "Expense Report Line" = rim; + + trigger OnRun() + var + ExpenseReportHeader: Record "Expense Report Header"; + begin + if ExpenseReportHeader.FindLast() then + FromExpenseReportNo := ExpenseReportHeader."No."; + + CreateExpenseReportToPost(); + + PostExpenseReport(); + end; + + [EventSubscriber(ObjectType::Codeunit, Codeunit::"Create Posted Expense Report", OnDefineExpenseAccountNo, '', false, false)] + local procedure OnDefineExpenseAccountNo(var AccountNo: Code[20]) + var + DEGLAccountNames: Codeunit "DE GL Account Names"; + ExpenseGLAccount: Codeunit "Create Expense G/L Account"; + begin + AccountNo := ExpenseGLAccount.FindGLAccountByName(DEGLAccountNames.SaleofResourcesName()); + end; + + local procedure CreateExpenseReportToPost() + var + Expense: Record Expense; + ExpenseReportHeader: Record "Expense Report Header"; + CreateEmployee: Codeunit "Create Employee"; + CreateCurrency: Codeunit "Create Currency"; + ContosoUtility: Codeunit "Contoso Utilities"; + CreateExpenseUser: Codeunit "Create Expense User"; + CreateExpenseLocation: Codeunit "Create Expense Location"; + ContosoExpenseAgent: Codeunit "Contoso Expense Agent"; + CreateExpCategories: Codeunit "Create Expense Categories DM"; + DEExpCategories: Codeunit "DE Exp. Categories"; + CreateExpenseSubcategories: Codeunit "Create Expense Subcategories"; + CreateExpensePaymentMethod: Codeunit "Create Expense Payment Method"; + begin + ExpenseReportHeader := ContosoExpenseAgent.InsertExpenseReportHeader(CreateExpenseUser.JO(), ContosoUtility.AdjustDate(19021104D), ContosoUtility.AdjustDate(19021104D)); + Expense := ContosoExpenseAgent.InsertExpense(CreateExpenseUser.JO(), DEExpCategories.PerDiem(), CreateExpenseLocation.GermanyAll(), BusinessTripToHamburgLbl, '', ContosoUtility.AdjustDate(19021103D), '', 0, '', CreateExpensePaymentMethod.Cash(), true, false, '', CreateDateTime(ContosoUtility.AdjustDate(19021024D), 064500T), CreateDateTime(ContosoUtility.AdjustDate(19021027D), 161500T), 0, 0, '', '', '', '', ''); + ReleaseAndAddExpenseToExpenseReport(Expense, ExpenseReportHeader); + Expense := ContosoExpenseAgent.InsertExpense(CreateExpenseUser.JO(), CreateExpCategories.Airline(), '', AirlineTicketsLbl, '', ContosoUtility.AdjustDate(19021010D), '', 2042, MargieTravelLbl, CreateExpensePaymentMethod.Card(), true, false, '', 0DT, 0DT, 0, 0, '', '', 'TY6HJO', '', ''); + ReleaseAndAddExpenseToExpenseReport(Expense, ExpenseReportHeader); + + ExpenseReportHeader := ContosoExpenseAgent.InsertExpenseReportHeader(CreateExpenseUser.EH(), ContosoUtility.AdjustDate(19021204D), ContosoUtility.AdjustDate(19021204D)); + Expense := ContosoExpenseAgent.InsertExpense(CreateExpenseUser.EH(), CreateExpCategories.Airline(), '', AirlineTicketsDublinLbl, TravelToConferenceLbl, ContosoUtility.AdjustDate(19021106D), '', 3120, MargieTravelLbl, CreateExpensePaymentMethod.Card(), true, false, '', 0DT, 0DT, 0, 0, '', '', 'FIUXHJT', '', ''); + ReleaseAndAddExpenseToExpenseReport(Expense, ExpenseReportHeader); + Expense := ContosoExpenseAgent.InsertExpense(CreateExpenseUser.EH(), CreateExpCategories.Events(), '', ITConferenceLbl, '', ContosoUtility.AdjustDate(19021107D), CreateCurrency.EUR(), 1990, ProsewareIncLbl, CreateExpensePaymentMethod.Card(), true, false, '', 0DT, 0DT, 0, 0, '', '', 'G574576HJ656', '', ''); + ReleaseAndAddExpenseToExpenseReport(Expense, ExpenseReportHeader); + Expense := ContosoExpenseAgent.InsertExpense(CreateExpenseUser.EH(), CreateExpCategories.GroundTransportation(), '', TaxiLbl, '', ContosoUtility.AdjustDate(19021114D), CreateCurrency.EUR(), 45, TailwindTradersLbl, CreateExpensePaymentMethod.Cash(), true, false, '', 0DT, 0DT, 0, 0, '', '', '456845856867', '', ''); + ReleaseAndAddExpenseToExpenseReport(Expense, ExpenseReportHeader); + Expense := ContosoExpenseAgent.InsertExpense(CreateExpenseUser.EH(), CreateExpCategories.Entertain(), '', BusinessDinnerLbl, BusinessDinnerWithBigPotentialCustomersLbl, ContosoUtility.AdjustDate(19021116D), CreateCurrency.EUR(), 842, FourthCoffeeLbl, CreateExpensePaymentMethod.Card(), true, false, '', 0DT, 0DT, 0, 0, '', '', 'RT6457560034', '', ''); + ContosoExpenseAgent.InsertExpenseParticipant(Expense."No.", 10000, CreateExpCategories.Entertain(), Enum::"Expense Participant Type"::Employee, CreateEmployee.ManagingDirector(), '', '', '', '', ''); + ContosoExpenseAgent.InsertExpenseParticipant(Expense."No.", 20000, CreateExpCategories.Entertain(), Enum::"Expense Participant Type"::Employee, CreateEmployee.SalesManager(), '', '', '', '', ''); + ContosoExpenseAgent.InsertExpenseParticipant(Expense."No.", 30000, CreateExpCategories.Entertain(), Enum::"Expense Participant Type"::External, '', JesseHomerLbl, RelecloudLbl, '', CEOLbl, 'jesse.homer@contoso.com'); + ContosoExpenseAgent.InsertExpenseParticipant(Expense."No.", 40000, CreateExpCategories.Entertain(), Enum::"Expense Participant Type"::External, '', RobertTownesLbl, AdatumCorporationLbl, '', CEOLbl, 'robert.townes@contoso.com'); + ReleaseAndAddExpenseToExpenseReport(Expense, ExpenseReportHeader); + Expense := ContosoExpenseAgent.InsertExpense(CreateExpenseUser.EH(), CreateExpCategories.Hotels(), '', HotelStayLbl, '', ContosoUtility.AdjustDate(19021118D), CreateCurrency.EUR(), 2150, ContosoSuitesLbl, CreateExpensePaymentMethod.Card(), true, false, '', 0DT, 0DT, 0, 0, '', '', '64675S879CT987990004', '', ''); + ContosoExpenseAgent.InsertExpenseItemization(Expense."No.", 10000, CreateExpCategories.Hotels(), CreateExpenseSubcategories.Room(), AccommodationLbl, ContosoUtility.AdjustDate(19021114D), 390); + ContosoExpenseAgent.InsertExpenseItemization(Expense."No.", 20000, CreateExpCategories.Hotels(), CreateExpenseSubcategories.Breakfast(), BreakfastLbl, ContosoUtility.AdjustDate(19021115D), 35); + ContosoExpenseAgent.InsertExpenseItemization(Expense."No.", 30000, CreateExpCategories.Hotels(), CreateExpenseSubcategories.Room(), AccommodationLbl, ContosoUtility.AdjustDate(19021115D), 390); + ContosoExpenseAgent.InsertExpenseItemization(Expense."No.", 40000, CreateExpCategories.Hotels(), CreateExpenseSubcategories.Breakfast(), BreakfastLbl, ContosoUtility.AdjustDate(19021116D), 35); + ContosoExpenseAgent.InsertExpenseItemization(Expense."No.", 50000, CreateExpCategories.Hotels(), CreateExpenseSubcategories.Room(), AccommodationLbl, ContosoUtility.AdjustDate(19021116D), 390); + ContosoExpenseAgent.InsertExpenseItemization(Expense."No.", 60000, CreateExpCategories.Hotels(), CreateExpenseSubcategories.RoomService(), RoomServiceLbl, ContosoUtility.AdjustDate(19021116D), 145); + ContosoExpenseAgent.InsertExpenseItemization(Expense."No.", 70000, CreateExpCategories.Hotels(), CreateExpenseSubcategories.Breakfast(), BreakfastLbl, ContosoUtility.AdjustDate(19021117D), 35); + ContosoExpenseAgent.InsertExpenseItemization(Expense."No.", 80000, CreateExpCategories.Hotels(), CreateExpenseSubcategories.Room(), AccommodationLbl, ContosoUtility.AdjustDate(19021117D), 390); + ContosoExpenseAgent.InsertExpenseItemization(Expense."No.", 90000, CreateExpCategories.Hotels(), CreateExpenseSubcategories.Breakfast(), BreakfastLbl, ContosoUtility.AdjustDate(19021118D), 35); + ContosoExpenseAgent.InsertExpenseItemization(Expense."No.", 100000, CreateExpCategories.Hotels(), CreateExpenseSubcategories.Tax(), HotelTaxesLbl, ContosoUtility.AdjustDate(19021118D), 305); + ReleaseAndAddExpenseToExpenseReport(Expense, ExpenseReportHeader); + Expense := ContosoExpenseAgent.InsertExpense(CreateExpenseUser.EH(), CreateExpCategories.RentalCars(), '', CarRentalsLbl, '', ContosoUtility.AdjustDate(19021118D), CreateCurrency.EUR(), 622.45, VanArsdelLtdLbl, CreateExpensePaymentMethod.Card(), true, false, '', 0DT, 0DT, 0, 0, '', '', 'H6584769867J9J95789', '', ''); + ReleaseAndAddExpenseToExpenseReport(Expense, ExpenseReportHeader); + Expense := ContosoExpenseAgent.InsertExpense(CreateExpenseUser.EH(), CreateExpCategories.GroundTransportation(), '', TaxiLbl, '', ContosoUtility.AdjustDate(19021118D), CreateCurrency.EUR(), 71, TailwindTradersLbl, CreateExpensePaymentMethod.Cash(), true, false, '', 0DT, 0DT, 0, 0, '', '', '7456875687568', '', ''); + ReleaseAndAddExpenseToExpenseReport(Expense, ExpenseReportHeader); + Expense := ContosoExpenseAgent.InsertExpense(CreateExpenseUser.EH(), DEExpCategories.PerDiem(), CreateExpenseLocation.UKOther(), TripToUKLbl, '', ContosoUtility.AdjustDate(19021121D), '', 0, '', CreateExpensePaymentMethod.Cash(), true, false, '', CreateDateTime(ContosoUtility.AdjustDate(19021114D), 053000T), CreateDateTime(ContosoUtility.AdjustDate(19021118D), 220500T), 0, 0, '', '', '', '', ''); + UpdateExpensePerDiem(Expense."No.", 20000, false, false, true); + UpdateExpensePerDiem(Expense."No.", 40000, false, true, false); + ReleaseAndAddExpenseToExpenseReport(Expense, ExpenseReportHeader); + Expense := ContosoExpenseAgent.InsertExpense(CreateExpenseUser.EH(), DEExpCategories.PerDiem(), CreateExpenseLocation.Domestic(), TripToDoverLbl, '', ContosoUtility.AdjustDate(19021204D), '', 0, '', CreateExpensePaymentMethod.Cash(), true, false, '', CreateDateTime(ContosoUtility.AdjustDate(19021127D), 070000T), CreateDateTime(ContosoUtility.AdjustDate(19021129D), 145500T), 0, 0, '', '', '', '', ''); + ReleaseAndAddExpenseToExpenseReport(Expense, ExpenseReportHeader); + Expense := ContosoExpenseAgent.InsertExpense(CreateExpenseUser.EH(), CreateExpCategories.Mileage(), '', MileageLbl, '', ContosoUtility.AdjustDate(19031101D), '', 0, VanArsdelLtdLbl, CreateExpensePaymentMethod.Cash(), true, false, '', 0DT, 0DT, 0, 249, 'New York', 'Dover', 'H6584769867J9J95789', '', ''); + ReleaseAndAddExpenseToExpenseReport(Expense, ExpenseReportHeader); + end; + + var + FromExpenseReportNo: Code[20]; + BusinessTripToHamburgLbl: Label 'Business trip to Hamburg, DE', MaxLength = 100; + AirlineTicketsLbl: Label 'Airline tickets NY/FRANKFURT/HAMBURG/FRANKFURT/NY', MaxLength = 100; + MargieTravelLbl: Label 'Margie''s Travel', MaxLength = 100; + AirlineTicketsDublinLbl: Label 'Airline tickets NY/DUBLIN/NY', MaxLength = 100; + TravelToConferenceLbl: Label 'Travel to the conference', MaxLength = 100; + ITConferenceLbl: Label 'IT Conference', MaxLength = 100; + ProsewareIncLbl: Label 'Proseware, Inc.', MaxLength = 100; + TaxiLbl: Label 'Taxi', MaxLength = 100; + TailwindTradersLbl: Label 'Tailwind Traders', MaxLength = 100; + BusinessDinnerLbl: Label 'Business Dinner', MaxLength = 100; + BusinessDinnerWithBigPotentialCustomersLbl: Label 'Business dinner with a big potential customers', MaxLength = 100; + FourthCoffeeLbl: Label 'Fourth Coffee', MaxLength = 100; + JesseHomerLbl: Label 'Jesse Homer', MaxLength = 100; + RelecloudLbl: Label 'Relecloud', MaxLength = 100; + RobertTownesLbl: Label 'Robert Townes', MaxLength = 100; + AdatumCorporationLbl: Label 'Adatum Corporation', MaxLength = 100; + HotelStayLbl: Label 'Hotel stay', MaxLength = 100; + ContosoSuitesLbl: Label 'Contoso Suites', MaxLength = 100; + AccommodationLbl: Label 'Accommodation', MaxLength = 100; + BreakfastLbl: Label 'Breakfast', MaxLength = 100; + HotelTaxesLbl: Label 'Hotel Taxes', MaxLength = 100; + RoomServiceLbl: Label 'Room service', MaxLength = 100; + CarRentalsLbl: Label 'Car Rentals', MaxLength = 100; + VanArsdelLtdLbl: Label 'VanArsdel, Ltd.', MaxLength = 100; + TripToUKLbl: Label 'Trip to UK', MaxLength = 100; + TripToDoverLbl: Label 'Trip to Dover', MaxLength = 100; + MileageLbl: Label 'Mileage', MaxLength = 100; + CEOLbl: Label 'CEO', MaxLength = 30; + + local procedure ReleaseAndAddExpenseToExpenseReport(Expense: Record Expense; ExpenseReportHeader: Record "Expense Report Header") + var + ReleaseExpenseDocument: Codeunit "Release Expense Document"; + CreateExpenseReport: Codeunit "Create Expense Report"; + begin + Expense.Get(Expense."No."); + ReleaseExpenseDocument.Run(Expense); + + CreateExpenseReport.AddSingleExpenseToExpenseReport(Expense, ExpenseReportHeader); + end; + + local procedure PostExpenseReport() + var + ExpenseReportHeader: Record "Expense Report Header"; + begin + if FromExpenseReportNo <> '' then + ExpenseReportHeader.SetFilter("No.", '>%1', FromExpenseReportNo); + + if ExpenseReportHeader.FindSet() then + repeat + Codeunit.Run(Codeunit::"Expense Report-Post", ExpenseReportHeader); + until ExpenseReportHeader.Next() = 0; + end; + + local procedure UpdateExpensePerDiem(ExpenseNo: Code[20]; LineNo: Integer; Breakfast: Boolean; Lunch: Boolean; Dinner: Boolean) + var + ExpensePerDiem: Record "Expense Per Diem"; + begin + ExpensePerDiem.Get(ExpenseNo, LineNo); + + ExpensePerDiem.Validate(Breakfast, Breakfast); + ExpensePerDiem.Validate(Lunch, Lunch); + ExpensePerDiem.Validate(Dinner, Dinner); + ExpensePerDiem.Modify(); + end; +} diff --git a/src/Apps/W1/ExpenseAgent/demo data/Country/DE/DEUpdEmpPostingGrp.Codeunit.al b/src/Apps/W1/ExpenseAgent/demo data/Country/DE/DEUpdEmpPostingGrp.Codeunit.al new file mode 100644 index 00000000000..7d807dc1436 --- /dev/null +++ b/src/Apps/W1/ExpenseAgent/demo data/Country/DE/DEUpdEmpPostingGrp.Codeunit.al @@ -0,0 +1,32 @@ +// ------------------------------------------------------------------------------------------------ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. See License.txt in the project root for license information. +// ------------------------------------------------------------------------------------------------ +namespace Microsoft.ExpenseAgent; + +using Microsoft.DemoData.HumanResources; + +codeunit 8315 "DE Upd. Emp. Posting Grp" +{ + InherentEntitlements = X; + InherentPermissions = X; + + trigger OnRun() + begin + UpdateEmployeePostingGroup(); + end; + + local procedure UpdateEmployeePostingGroup() + var + HRGLAccount: Codeunit "Create HR GL Account"; + DEGLAccountNames: Codeunit "DE GL Account Names"; + ExpenseGLAccount: Codeunit "Create Expense G/L Account"; + DEExpGLAccount: Codeunit "DE Exp. GL Account"; + ContosoExpenseAgent: Codeunit "Contoso Expense Agent"; + CreateEmployeePostingGroup: Codeunit "Create Employee Posting Group"; + begin + ContosoExpenseAgent.SetOverwriteData(true); + ContosoExpenseAgent.UpdateEmployeePostingGroup(CreateEmployeePostingGroup.EmployeeExpenses(), ExpenseGLAccount.FindGLAccountByName(HRGLAccount.EmployeesPayableName()), ExpenseGLAccount.FindGLAccountByName(DEGLAccountNames.AssetsintheformofprepaidexpensesName()), ExpenseGLAccount.FindGLAccountByName(DEGLAccountNames.BusinessaccountOperatingDomesticName()), DEExpGLAccount.CompanyCreditCardsClearingAccount()); + ContosoExpenseAgent.SetOverwriteData(false); + end; +} diff --git a/src/Apps/W1/ExpenseAgent/demo data/Country/DK/DKCountryData.Codeunit.al b/src/Apps/W1/ExpenseAgent/demo data/Country/DK/DKCountryData.Codeunit.al new file mode 100644 index 00000000000..c04f734f319 --- /dev/null +++ b/src/Apps/W1/ExpenseAgent/demo data/Country/DK/DKCountryData.Codeunit.al @@ -0,0 +1,64 @@ +// ------------------------------------------------------------------------------------------------ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. See License.txt in the project root for license information. +// ------------------------------------------------------------------------------------------------ +namespace Microsoft.ExpenseAgent; + +codeunit 8288 "DK Country Data" implements "Expense Agent Country Data" +{ + Access = Internal; + InherentEntitlements = X; + InherentPermissions = X; + + procedure CreateSetupData() + var + W1CountryData: Codeunit "W1 Country Data"; + DKExpGLAccount: Codeunit "DK Exp. GL Account"; + DKExpPostingGrp: Codeunit "DK Exp. Posting Grp"; + begin + BindSubscription(DKExpGLAccount); + BindSubscription(DKExpPostingGrp); + + W1CountryData.CreateSetupData(); + Codeunit.Run(Codeunit::"DK Upd. Emp. Posting Grp"); + Codeunit.Run(Codeunit::"DK Exp. Posting Grp"); + + UnbindSubscription(DKExpPostingGrp); + UnbindSubscription(DKExpGLAccount); + end; + + procedure CreateMasterData() + var + W1CountryData: Codeunit "W1 Country Data"; + begin + W1CountryData.CreateMasterData(); + Codeunit.Run(Codeunit::"DK Exp. Categories"); + Codeunit.Run(Codeunit::"DK Exp. SubCategories"); + Codeunit.Run(Codeunit::"DK Exp. Rule Header"); + Codeunit.Run(Codeunit::"DK Exp. Rule Condition"); + end; + + procedure CreateTransactionalData() + var + W1CountryData: Codeunit "W1 Country Data"; + begin + W1CountryData.CreateTransactionalData(); + Codeunit.Run(Codeunit::"DK Expense"); + end; + + procedure CreateHistoricalData() + var + W1CountryData: Codeunit "W1 Country Data"; + DKCurrencySwapSub: Codeunit "DK Currency Swap Sub"; + DKPostedExpReport: Codeunit "DK Posted Exp. Report"; + begin + BindSubscription(DKCurrencySwapSub); + BindSubscription(DKPostedExpReport); + + W1CountryData.CreateHistoricalData(); + Codeunit.Run(Codeunit::"DK Posted Exp. Report"); + + UnbindSubscription(DKPostedExpReport); + UnbindSubscription(DKCurrencySwapSub); + end; +} diff --git a/src/Apps/W1/ExpenseAgent/demo data/Country/DK/DKCurrencySwapSub.Codeunit.al b/src/Apps/W1/ExpenseAgent/demo data/Country/DK/DKCurrencySwapSub.Codeunit.al new file mode 100644 index 00000000000..c758e910d02 --- /dev/null +++ b/src/Apps/W1/ExpenseAgent/demo data/Country/DK/DKCurrencySwapSub.Codeunit.al @@ -0,0 +1,24 @@ +// ------------------------------------------------------------------------------------------------ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. See License.txt in the project root for license information. +// ------------------------------------------------------------------------------------------------ +namespace Microsoft.ExpenseAgent; + +using Microsoft.DemoData.Finance; + +codeunit 8299 "DK Currency Swap Sub" +{ + SingleInstance = true; + EventSubscriberInstance = Manual; + InherentEntitlements = X; + InherentPermissions = X; + + [EventSubscriber(ObjectType::Codeunit, Codeunit::"Contoso Expense Agent", OnBeforeValidateCurrencyCodeInExpense, '', false, false)] + local procedure OnBeforeValidateCurrencyCodeInExpense(var CurrencyCode: Code[10]) + var + CreateCurrency: Codeunit "Create Currency"; + begin + if CurrencyCode = CreateCurrency.DKK() then + CurrencyCode := ''; + end; +} diff --git a/src/Apps/W1/ExpenseAgent/demo data/Country/DK/DKExpCategories.Codeunit.al b/src/Apps/W1/ExpenseAgent/demo data/Country/DK/DKExpCategories.Codeunit.al new file mode 100644 index 00000000000..7daebfd0570 --- /dev/null +++ b/src/Apps/W1/ExpenseAgent/demo data/Country/DK/DKExpCategories.Codeunit.al @@ -0,0 +1,31 @@ +// ------------------------------------------------------------------------------------------------ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. See License.txt in the project root for license information. +// ------------------------------------------------------------------------------------------------ +namespace Microsoft.ExpenseAgent; + +codeunit 8293 "DK Exp. Categories" +{ + InherentEntitlements = X; + InherentPermissions = X; + + trigger OnRun() + var + CreateExpenseGroup: Codeunit "Create Expense Group"; + CreateExpensePaymentMethod: Codeunit "Create Expense Payment Method"; + ContosoExpenseAgent: Codeunit "Contoso Expense Agent"; + DKExpPostingGrp: Codeunit "DK Exp. Posting Grp"; + begin + ContosoExpenseAgent.InsertExpenseCategory(PerDiem(), PerDiemByAssignedPolicyLbl, PerDiemByAssignedPolicyPostingLbl, DKExpPostingGrp.ExpensePerDiem(), Enum::"Expense Attachment Enforcement"::" ", CreateExpensePaymentMethod.Cash(), false, false, CreateExpenseGroup.Travel(), true, Enum::"Expense Reimbursement Type"::"Employee Paid", Enum::"Expense Detail Needed"::"Per Diem"); + end; + + var + PerDiemTok: Label 'PER-DIEM', MaxLength = 20, Locked = true; + PerDiemByAssignedPolicyLbl: Label 'Expenses for per-diem or daily allowance paid for business trips, typically based on travel itinerary or other proof of travel (e.g., booking or agenda), rather than individual expense receipts.', MaxLength = 250; + PerDiemByAssignedPolicyPostingLbl: Label 'Per-diem by assigned policy', MaxLength = 100; + + procedure PerDiem(): Code[20] + begin + exit(PerDiemTok); + end; +} diff --git a/src/Apps/W1/ExpenseAgent/demo data/Country/DK/DKExpGLAccount.Codeunit.al b/src/Apps/W1/ExpenseAgent/demo data/Country/DK/DKExpGLAccount.Codeunit.al new file mode 100644 index 00000000000..a12d64bf42b --- /dev/null +++ b/src/Apps/W1/ExpenseAgent/demo data/Country/DK/DKExpGLAccount.Codeunit.al @@ -0,0 +1,105 @@ +// ------------------------------------------------------------------------------------------------ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. See License.txt in the project root for license information. +// ------------------------------------------------------------------------------------------------ +namespace Microsoft.ExpenseAgent; + +using Microsoft.DemoTool.Helpers; +using Microsoft.Finance.GeneralLedger.Account; +using Microsoft.Foundation.Enums; + +codeunit 8290 "DK Exp. GL Account" +{ + SingleInstance = true; + EventSubscriberInstance = Manual; + InherentEntitlements = X; + InherentPermissions = X; + + [EventSubscriber(ObjectType::Codeunit, Codeunit::"Create Expense G/L Account", 'OnAfterAddGLAccountsForLocalization', '', false, false)] + local procedure ModifyGLAccount() + var + GLAccountCategory: Record "G/L Account Category"; + SubCategory: Text[80]; + begin + AddGLAccounts(); + + SubCategory := Format(GLAccountCategory."Account Category"::Assets, 80); + ContosoGLAccount.InsertGLAccount(CompanyCreditCards(), CompanyCreditCardsName(), "G/L Account Income/Balance"::"Balance Sheet", Enum::"G/L Account Category"::Assets, SubCategory, Enum::"G/L Account Type"::Posting, '', '', '', 0, '', Enum::"General Posting Type"::" ", '', '', true, false, false); + + SubCategory := Format(GLAccountCategory."Account Category"::Expense, 80); + ContosoGLAccount.InsertGLAccount(TravelAllowancesPerDiem(), TravelAllowancesPerDiemName(), "G/L Account Income/Balance"::"Income Statement", Enum::"G/L Account Category"::Expense, SubCategory, Enum::"G/L Account Type"::Posting, '', '', '', 0, '', Enum::"General Posting Type"::Purchase, '', '', true, false, false); + ContosoGLAccount.InsertGLAccount(ExpenseGLAccount.MealExpensesNondeductibleAccount(), ExpenseGLAccount.MealExpensesNondeductibleAccountName(), "G/L Account Income/Balance"::"Income Statement", Enum::"G/L Account Category"::Expense, SubCategory, Enum::"G/L Account Type"::Posting, '', '', '', 0, '', Enum::"General Posting Type"::Purchase, '', '', true, false, false); + ContosoGLAccount.InsertGLAccount(NonDeductibleTravelExpenses(), NonDeductibleTravelExpensesName(), "G/L Account Income/Balance"::"Income Statement", Enum::"G/L Account Category"::Expense, SubCategory, Enum::"G/L Account Type"::Posting, '', '', '', 0, '', Enum::"General Posting Type"::Purchase, '', '', true, false, false); + ContosoGLAccount.InsertGLAccount(RentalCarExpenses(), RentalCarExpensesName(), "G/L Account Income/Balance"::"Income Statement", Enum::"G/L Account Category"::Expense, SubCategory, Enum::"G/L Account Type"::Posting, '', '', '', 0, '', Enum::"General Posting Type"::Purchase, '', '', true, false, false); + ContosoGLAccount.InsertGLAccount(OtherExpenses(), OtherExpensesName(), "G/L Account Income/Balance"::"Income Statement", Enum::"G/L Account Category"::Expense, SubCategory, Enum::"G/L Account Type"::Posting, '', '', '', 0, '', Enum::"General Posting Type"::Purchase, '', '', true, false, false); + end; + + local procedure AddGLAccounts() + begin + ContosoGLAccount.AddAccountForLocalization(CompanyCreditCardsName(), '18300'); + ContosoGLAccount.AddAccountForLocalization(TravelAllowancesPerDiemName(), '03652'); + ContosoGLAccount.AddAccountForLocalization(ExpenseGLAccount.MealExpensesNondeductibleAccountName(), '03661'); + ContosoGLAccount.AddAccountForLocalization(NonDeductibleTravelExpensesName(), '03655'); + ContosoGLAccount.AddAccountForLocalization(RentalCarExpensesName(), '03654'); + ContosoGLAccount.AddAccountForLocalization(OtherExpensesName(), '05699'); + end; + + var + ContosoGLAccount: Codeunit "Contoso GL Account"; + ExpenseGLAccount: Codeunit "Create Expense G/L Account"; + CompanyCreditCardsTok: Label 'Company credit cards', MaxLength = 100; + TravelAllowancesPerDiemTok: Label 'Travel allowances (per diem)', MaxLength = 100; + RentalCarExpensesTok: Label 'Rental car expenses', MaxLength = 100; + NonDeductibleTravelExpensesTok: Label 'Non-deductible travel expenses', MaxLength = 100; + OtherExpensesTok: Label 'Other expenses', MaxLength = 100; + + procedure CompanyCreditCards(): Code[20] + begin + exit(ContosoGLAccount.GetAccountNo(CompanyCreditCardsName())); + end; + + procedure CompanyCreditCardsName(): Text[100] + begin + exit(CompanyCreditCardsTok); + end; + + procedure TravelAllowancesPerDiem(): Code[20] + begin + exit(ContosoGLAccount.GetAccountNo(TravelAllowancesPerDiemName())); + end; + + procedure TravelAllowancesPerDiemName(): Text[100] + begin + exit(TravelAllowancesPerDiemTok); + end; + + procedure RentalCarExpenses(): Code[20] + begin + exit(ContosoGLAccount.GetAccountNo(RentalCarExpensesName())); + end; + + procedure RentalCarExpensesName(): Text[100] + begin + exit(RentalCarExpensesTok); + end; + + procedure NonDeductibleTravelExpenses(): Code[20] + begin + exit(ContosoGLAccount.GetAccountNo(NonDeductibleTravelExpensesName())); + end; + + procedure NonDeductibleTravelExpensesName(): Text[100] + begin + exit(NonDeductibleTravelExpensesTok); + end; + + procedure OtherExpenses(): Code[20] + begin + exit(ContosoGLAccount.GetAccountNo(OtherExpensesName())); + end; + + procedure OtherExpensesName(): Text[100] + begin + exit(OtherExpensesTok); + end; +} diff --git a/src/Apps/W1/ExpenseAgent/demo data/Country/DK/DKExpPostingGrp.Codeunit.al b/src/Apps/W1/ExpenseAgent/demo data/Country/DK/DKExpPostingGrp.Codeunit.al new file mode 100644 index 00000000000..239a998e5fb --- /dev/null +++ b/src/Apps/W1/ExpenseAgent/demo data/Country/DK/DKExpPostingGrp.Codeunit.al @@ -0,0 +1,64 @@ +// ------------------------------------------------------------------------------------------------ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. See License.txt in the project root for license information. +// ------------------------------------------------------------------------------------------------ +namespace Microsoft.ExpenseAgent; + +codeunit 8291 "DK Exp. Posting Grp" +{ + SingleInstance = true; + EventSubscriberInstance = Manual; + InherentEntitlements = X; + InherentPermissions = X; + + trigger OnRun() + var + ContosoExpenseAgent: Codeunit "Contoso Expense Agent"; + begin + ContosoExpenseAgent.InsertExpensePostingGroup(ExpensePerDiem(), ExpensePerDiemLbl); + end; + + [EventSubscriber(ObjectType::Table, Database::"Expense Posting Group", 'OnBeforeInsertEvent', '', false, false)] + local procedure OnInsertRecord(var Rec: Record "Expense Posting Group") + var + DKGLAccountNames: Codeunit "DK GL Account Names"; + ExpenseGLAccount: Codeunit "Create Expense G/L Account"; + DKExpGLAccount: Codeunit "DK Exp. GL Account"; + CreateExpensePostingGroup: Codeunit "Create Expense Posting Group"; + begin + case Rec.Code of + CreateExpensePostingGroup.ExpenseEntertainment(): + ValidateRecordFields(Rec, ExpenseGLAccount.FindGLAccountByName(DKGLAccountNames.EntwinetobaccospiritsName()), '', ExpenseGLAccount.FindGLAccountByName(DKGLAccountNames.PrepaymentsAccruedCostsName()), ExpenseGLAccount.FindGLAccountByName(DKGLAccountNames.CentdiscrepanciesName()), ExpenseGLAccount.FindGLAccountByName(DKGLAccountNames.CentdiscrepanciesName())); + CreateExpensePostingGroup.ExpenseMeals(): + ValidateRecordFields(Rec, ExpenseGLAccount.FindGLAccountByName(DKGLAccountNames.RestaurantdiningName()), ExpenseGLAccount.MealExpensesNondeductibleAccount(), ExpenseGLAccount.FindGLAccountByName(DKGLAccountNames.PrepaymentsAccruedCostsName()), ExpenseGLAccount.FindGLAccountByName(DKGLAccountNames.CentdiscrepanciesName()), ExpenseGLAccount.FindGLAccountByName(DKGLAccountNames.CentdiscrepanciesName())); + CreateExpensePostingGroup.ExpenseMileage(): + ValidateRecordFields(Rec, ExpenseGLAccount.FindGLAccountByName(DKGLAccountNames.MileagerateName()), '', ExpenseGLAccount.FindGLAccountByName(DKGLAccountNames.PrepaymentsAccruedCostsName()), ExpenseGLAccount.FindGLAccountByName(DKGLAccountNames.CentdiscrepanciesName()), ExpenseGLAccount.FindGLAccountByName(DKGLAccountNames.CentdiscrepanciesName())); + CreateExpensePostingGroup.ExpenseOther(): + ValidateRecordFields(Rec, DKExpGLAccount.OtherExpenses(), DKExpGLAccount.NonDeductibleTravelExpenses(), ExpenseGLAccount.FindGLAccountByName(DKGLAccountNames.PrepaymentsAccruedCostsName()), ExpenseGLAccount.FindGLAccountByName(DKGLAccountNames.CentdiscrepanciesName()), ExpenseGLAccount.FindGLAccountByName(DKGLAccountNames.CentdiscrepanciesName())); + ExpensePerDiem(): + ValidateRecordFields(Rec, DKExpGLAccount.TravelAllowancesPerDiem(), '', ExpenseGLAccount.FindGLAccountByName(DKGLAccountNames.PrepaymentsAccruedCostsName()), ExpenseGLAccount.FindGLAccountByName(DKGLAccountNames.CentdiscrepanciesName()), ExpenseGLAccount.FindGLAccountByName(DKGLAccountNames.CentdiscrepanciesName())); + CreateExpensePostingGroup.ExpenseTravel(): + ValidateRecordFields(Rec, ExpenseGLAccount.FindGLAccountByName(DKGLAccountNames.TravelingtradefairsetcName()), DKExpGLAccount.NonDeductibleTravelExpenses(), ExpenseGLAccount.FindGLAccountByName(DKGLAccountNames.PrepaymentsAccruedCostsName()), ExpenseGLAccount.FindGLAccountByName(DKGLAccountNames.CentdiscrepanciesName()), ExpenseGLAccount.FindGLAccountByName(DKGLAccountNames.CentdiscrepanciesName())); + CreateExpensePostingGroup.ExpenseRentalCars(): + ValidateRecordFields(Rec, DKExpGLAccount.RentalCarExpenses(), '', ExpenseGLAccount.FindGLAccountByName(DKGLAccountNames.PrepaymentsAccruedCostsName()), ExpenseGLAccount.FindGLAccountByName(DKGLAccountNames.CentdiscrepanciesName()), ExpenseGLAccount.FindGLAccountByName(DKGLAccountNames.CentdiscrepanciesName())); + end; + end; + + local procedure ValidateRecordFields(var ExpensePostingGroup: Record "Expense Posting Group"; RefundableDebitAccount: Code[20]; NonRefundableDebitAccount: Code[20]; PrepaymentCreditAccount: Code[20]; ExpenseDebitRoundingAccount: Code[20]; ExpenseCreditRoundingAccount: Code[20]) + begin + ExpensePostingGroup.Validate("Refundable Debit Account", RefundableDebitAccount); + ExpensePostingGroup.Validate("Non-Refundable Debit Account", NonRefundableDebitAccount); + ExpensePostingGroup.Validate("Prepayment Credit Account", PrepaymentCreditAccount); + ExpensePostingGroup.Validate("Debit Rounding Account", ExpenseDebitRoundingAccount); + ExpensePostingGroup.Validate("Credit Rounding Account", ExpenseCreditRoundingAccount); + end; + + var + ExpensePERDIEMTok: Label 'EXPENSE-PERDIEM', MaxLength = 20, Locked = true; + ExpensePerDiemLbl: Label 'Expense - Per Diem', MaxLength = 100; + + procedure ExpensePerDiem(): Code[20] + begin + exit(ExpensePERDIEMTok); + end; +} diff --git a/src/Apps/W1/ExpenseAgent/demo data/Country/DK/DKExpRuleCondition.Codeunit.al b/src/Apps/W1/ExpenseAgent/demo data/Country/DK/DKExpRuleCondition.Codeunit.al new file mode 100644 index 00000000000..1307ba6672d --- /dev/null +++ b/src/Apps/W1/ExpenseAgent/demo data/Country/DK/DKExpRuleCondition.Codeunit.al @@ -0,0 +1,26 @@ +// ------------------------------------------------------------------------------------------------ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. See License.txt in the project root for license information. +// ------------------------------------------------------------------------------------------------ +namespace Microsoft.ExpenseAgent; + +codeunit 8296 "DK Exp. Rule Condition" +{ + InherentEntitlements = X; + InherentPermissions = X; + + trigger OnRun() + var + DKExpCategories: Codeunit "DK Exp. Categories"; + CreateExpenseLocation: Codeunit "Create Expense Location"; + ContosoExpenseAgent: Codeunit "Contoso Expense Agent"; + begin + ContosoExpenseAgent.InsertExpenseRuleCondition(DKExpCategories.PerDiem(), CreateExpenseLocation.CanadaAll(), 0D, 10000, Enum::"Expense Rule Condition Type"::"Daily Rate", 125); + ContosoExpenseAgent.InsertExpenseRuleCondition(DKExpCategories.PerDiem(), CreateExpenseLocation.DenmarkAll(), 0D, 10000, Enum::"Expense Rule Condition Type"::"Daily Rate", 450); + ContosoExpenseAgent.InsertExpenseRuleCondition(DKExpCategories.PerDiem(), CreateExpenseLocation.Domestic(), 0D, 10000, Enum::"Expense Rule Condition Type"::"Daily Rate", 50); + ContosoExpenseAgent.InsertExpenseRuleCondition(DKExpCategories.PerDiem(), CreateExpenseLocation.FranceAll(), 0D, 10000, Enum::"Expense Rule Condition Type"::"Daily Rate", 110); + ContosoExpenseAgent.InsertExpenseRuleCondition(DKExpCategories.PerDiem(), CreateExpenseLocation.GermanyAll(), 0D, 10000, Enum::"Expense Rule Condition Type"::"Daily Rate", 105); + ContosoExpenseAgent.InsertExpenseRuleCondition(DKExpCategories.PerDiem(), CreateExpenseLocation.UKOther(), 0D, 10000, Enum::"Expense Rule Condition Type"::"Daily Rate", 115); + ContosoExpenseAgent.InsertExpenseRuleCondition(DKExpCategories.PerDiem(), CreateExpenseLocation.USAOther(), 0D, 10000, Enum::"Expense Rule Condition Type"::"Daily Rate", 120); + end; +} diff --git a/src/Apps/W1/ExpenseAgent/demo data/Country/DK/DKExpRuleHeader.Codeunit.al b/src/Apps/W1/ExpenseAgent/demo data/Country/DK/DKExpRuleHeader.Codeunit.al new file mode 100644 index 00000000000..b2497fbfa4d --- /dev/null +++ b/src/Apps/W1/ExpenseAgent/demo data/Country/DK/DKExpRuleHeader.Codeunit.al @@ -0,0 +1,29 @@ +// ------------------------------------------------------------------------------------------------ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. See License.txt in the project root for license information. +// ------------------------------------------------------------------------------------------------ +namespace Microsoft.ExpenseAgent; + +using Microsoft.DemoData.Finance; + +codeunit 8295 "DK Exp. Rule Header" +{ + InherentEntitlements = X; + InherentPermissions = X; + + trigger OnRun() + var + CreateCurrency: Codeunit "Create Currency"; + DKExpCategories: Codeunit "DK Exp. Categories"; + CreateExpenseLocation: Codeunit "Create Expense Location"; + ContosoExpenseAgent: Codeunit "Contoso Expense Agent"; + begin + ContosoExpenseAgent.InsertExpenseRuleHeader(DKExpCategories.PerDiem(), CreateExpenseLocation.CanadaAll(), 0D, Enum::"Expense Justification"::" ", false, '', CreateCurrency.CAD(), ''); + ContosoExpenseAgent.InsertExpenseRuleHeader(DKExpCategories.PerDiem(), CreateExpenseLocation.DenmarkAll(), 0D, Enum::"Expense Justification"::" ", false, '', CreateCurrency.EUR(), ''); + ContosoExpenseAgent.InsertExpenseRuleHeader(DKExpCategories.PerDiem(), CreateExpenseLocation.Domestic(), 0D, Enum::"Expense Justification"::" ", false, '', '', ''); + ContosoExpenseAgent.InsertExpenseRuleHeader(DKExpCategories.PerDiem(), CreateExpenseLocation.FranceAll(), 0D, Enum::"Expense Justification"::" ", false, '', CreateCurrency.EUR(), ''); + ContosoExpenseAgent.InsertExpenseRuleHeader(DKExpCategories.PerDiem(), CreateExpenseLocation.GermanyAll(), 0D, Enum::"Expense Justification"::" ", false, '', CreateCurrency.EUR(), ''); + ContosoExpenseAgent.InsertExpenseRuleHeader(DKExpCategories.PerDiem(), CreateExpenseLocation.UKOther(), 0D, Enum::"Expense Justification"::" ", false, '', CreateCurrency.GBP(), ''); + ContosoExpenseAgent.InsertExpenseRuleHeader(DKExpCategories.PerDiem(), CreateExpenseLocation.USAOther(), 0D, Enum::"Expense Justification"::" ", false, '', '', ''); + end; +} diff --git a/src/Apps/W1/ExpenseAgent/demo data/Country/DK/DKExpSubCategories.Codeunit.al b/src/Apps/W1/ExpenseAgent/demo data/Country/DK/DKExpSubCategories.Codeunit.al new file mode 100644 index 00000000000..d4f5e16164a --- /dev/null +++ b/src/Apps/W1/ExpenseAgent/demo data/Country/DK/DKExpSubCategories.Codeunit.al @@ -0,0 +1,39 @@ +// ------------------------------------------------------------------------------------------------ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. See License.txt in the project root for license information. +// ------------------------------------------------------------------------------------------------ +namespace Microsoft.ExpenseAgent; + +codeunit 8294 "DK Exp. SubCategories" +{ + InherentEntitlements = X; + InherentPermissions = X; + + trigger OnRun() + var + ContosoExpenseAgent: Codeunit "Contoso Expense Agent"; + DKExpCategories: Codeunit "DK Exp. Categories"; + begin + // PER-DIEM subcategories + ContosoExpenseAgent.InsertExpenseSubcategory(Country(), DKExpCategories.PerDiem(), LocalCountryPerDiemLbl, LocalCountryPerDiemPostingLbl, false, true, false); + ContosoExpenseAgent.InsertExpenseSubcategory(Intl(), DKExpCategories.PerDiem(), InternationalPerDiemLbl, InternationalPerDiemPostingLbl, false, true, false); + end; + + var + CountryTok: Label 'COUNTRY', MaxLength = 20, Locked = true; + IntlTok: Label 'INTL', MaxLength = 20, Locked = true; + LocalCountryPerDiemLbl: Label 'Daily per-diem allowance based on domestic travel rates, paid instead of individual meal or incidental expense reimbursements.', MaxLength = 250; + InternationalPerDiemLbl: Label 'Daily per-diem allowance for international business travel, based on applicable foreign travel rates.', MaxLength = 250; + LocalCountryPerDiemPostingLbl: Label 'Local country per-diem', MaxLength = 100; + InternationalPerDiemPostingLbl: Label 'International per-diem', MaxLength = 100; + + procedure Country(): Code[20] + begin + exit(CountryTok); + end; + + procedure Intl(): Code[20] + begin + exit(IntlTok); + end; +} diff --git a/src/Apps/W1/ExpenseAgent/demo data/Country/DK/DKExpense.Codeunit.al b/src/Apps/W1/ExpenseAgent/demo data/Country/DK/DKExpense.Codeunit.al new file mode 100644 index 00000000000..1d7bdc59341 --- /dev/null +++ b/src/Apps/W1/ExpenseAgent/demo data/Country/DK/DKExpense.Codeunit.al @@ -0,0 +1,51 @@ +// ------------------------------------------------------------------------------------------------ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. See License.txt in the project root for license information. +// ------------------------------------------------------------------------------------------------ +namespace Microsoft.ExpenseAgent; + +using Microsoft.DemoTool.Helpers; + +codeunit 8297 "DK Expense" +{ + InherentEntitlements = X; + InherentPermissions = X; + Permissions = tabledata "Expense Per Diem" = rim; + + trigger OnRun() + begin + CreateOpenExpense(); + end; + + local procedure CreateOpenExpense() + var + Expense: Record Expense; + ContosoExpenseAgent: Codeunit "Contoso Expense Agent"; + CreateExpenseLocation: Codeunit "Create Expense Location"; + begin + Expense := ContosoExpenseAgent.InsertExpense(CreateExpenseUser.EH(), DKExpCategories.PerDiem(), CreateExpenseLocation.DenmarkAll(), PerDiemByAssignedPolicyLbl, '', ContosoUtility.AdjustDate(19030203D), '', 0, '', CreateExpensePaymentMethod.Cash(), true, false, '', CreateDateTime(ContosoUtility.AdjustDate(19030115D), 144000T), CreateDateTime(ContosoUtility.AdjustDate(19030121D), 000500T), 0, 0, '', '', '', '', ''); + UpdateExpensePerDiem(Expense."No.", 10000, false, false, true); + UpdateExpensePerDiem(Expense."No.", 30000, false, true, false); + UpdateExpensePerDiem(Expense."No.", 40000, false, false, true); + UpdateExpensePerDiem(Expense."No.", 60000, false, true, true); + end; + + var + ContosoUtility: Codeunit "Contoso Utilities"; + CreateExpenseUser: Codeunit "Create Expense User"; + DKExpCategories: Codeunit "DK Exp. Categories"; + CreateExpensePaymentMethod: Codeunit "Create Expense Payment Method"; + PerDiemByAssignedPolicyLbl: Label 'Per-diem by assigned policy', MaxLength = 100; + + local procedure UpdateExpensePerDiem(ExpenseNo: Code[20]; LineNo: Integer; Breakfast: Boolean; Lunch: Boolean; Dinner: Boolean) + var + ExpensePerDiem: Record "Expense Per Diem"; + begin + ExpensePerDiem.Get(ExpenseNo, LineNo); + + ExpensePerDiem.Validate(Breakfast, Breakfast); + ExpensePerDiem.Validate(Lunch, Lunch); + ExpensePerDiem.Validate(Dinner, Dinner); + ExpensePerDiem.Modify(); + end; +} diff --git a/src/Apps/W1/ExpenseAgent/demo data/Country/DK/DKGLAccountNames.Codeunit.al b/src/Apps/W1/ExpenseAgent/demo data/Country/DK/DKGLAccountNames.Codeunit.al new file mode 100644 index 00000000000..f318d36cf2b --- /dev/null +++ b/src/Apps/W1/ExpenseAgent/demo data/Country/DK/DKGLAccountNames.Codeunit.al @@ -0,0 +1,68 @@ +// ------------------------------------------------------------------------------------------------ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. See License.txt in the project root for license information. +// ------------------------------------------------------------------------------------------------ +namespace Microsoft.ExpenseAgent; + +codeunit 8289 "DK GL Account Names" +{ + Access = Internal; + InherentEntitlements = X; + InherentPermissions = X; + + var + EntwinetobaccospiritsTok: Label 'Ent., Wine / Tobacco / Spirits', MaxLength = 100; + PrepaymentsAccruedCostsTok: Label 'Prepayments - Accrued Costs', MaxLength = 100; + CentdiscrepanciesTok: Label 'Cent Discrepancies', MaxLength = 100; + RestaurantdiningTok: Label 'Restaurant Dining', MaxLength = 100; + MileagerateTok: Label 'Mileage Rate', MaxLength = 100; + TravelingtradefairsetcTok: Label 'Traveling, Trade Fairs etc.', MaxLength = 100; + AccountsPayablePostingTok: Label 'Accounts Payables', MaxLength = 100; + BankTok: Label 'Bank', MaxLength = 100; + DomesticsalesofgoodsandservicesTok: Label 'Domestic Sales of Goods and Services', MaxLength = 100; + + procedure EntwinetobaccospiritsName(): Text[100] + begin + exit(EntwinetobaccospiritsTok); + end; + + procedure PrepaymentsAccruedCostsName(): Text[100] + begin + exit(PrepaymentsAccruedCostsTok); + end; + + procedure CentdiscrepanciesName(): Text[100] + begin + exit(CentdiscrepanciesTok); + end; + + procedure RestaurantdiningName(): Text[100] + begin + exit(RestaurantdiningTok); + end; + + procedure MileagerateName(): Text[100] + begin + exit(MileagerateTok); + end; + + procedure TravelingtradefairsetcName(): Text[100] + begin + exit(TravelingtradefairsetcTok); + end; + + procedure AccountsPayablePostingName(): Text[100] + begin + exit(AccountsPayablePostingTok); + end; + + procedure BankName(): Text[100] + begin + exit(BankTok); + end; + + procedure DomesticsalesofgoodsandservicesName(): Text[100] + begin + exit(DomesticsalesofgoodsandservicesTok); + end; +} diff --git a/src/Apps/W1/ExpenseAgent/demo data/Country/DK/DKPostedExpReport.Codeunit.al b/src/Apps/W1/ExpenseAgent/demo data/Country/DK/DKPostedExpReport.Codeunit.al new file mode 100644 index 00000000000..26157d0fd23 --- /dev/null +++ b/src/Apps/W1/ExpenseAgent/demo data/Country/DK/DKPostedExpReport.Codeunit.al @@ -0,0 +1,168 @@ +// ------------------------------------------------------------------------------------------------ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. See License.txt in the project root for license information. +// ------------------------------------------------------------------------------------------------ +namespace Microsoft.ExpenseAgent; + +using Microsoft.DemoData.Finance; +using Microsoft.DemoData.HumanResources; +using Microsoft.DemoTool.Helpers; + +codeunit 8298 "DK Posted Exp. Report" +{ + SingleInstance = true; + EventSubscriberInstance = Manual; + InherentEntitlements = X; + InherentPermissions = X; + Permissions = + tabledata "Expense Per Diem" = rim, + tabledata "Expense Report Line" = rim; + + trigger OnRun() + var + ExpenseReportHeader: Record "Expense Report Header"; + begin + if ExpenseReportHeader.FindLast() then + FromExpenseReportNo := ExpenseReportHeader."No."; + + CreateExpenseReportToPost(); + + PostExpenseReport(); + end; + + [EventSubscriber(ObjectType::Codeunit, Codeunit::"Create Posted Expense Report", OnDefineExpenseAccountNo, '', false, false)] + local procedure OnDefineExpenseAccountNo(var AccountNo: Code[20]) + var + DKGLAccountNames: Codeunit "DK GL Account Names"; + ExpenseGLAccount: Codeunit "Create Expense G/L Account"; + begin + AccountNo := ExpenseGLAccount.FindGLAccountByName(DKGLAccountNames.DomesticsalesofgoodsandservicesName()); + end; + + local procedure CreateExpenseReportToPost() + var + Expense: Record Expense; + ExpenseReportHeader: Record "Expense Report Header"; + CreateEmployee: Codeunit "Create Employee"; + CreateCurrency: Codeunit "Create Currency"; + ContosoUtility: Codeunit "Contoso Utilities"; + CreateExpenseUser: Codeunit "Create Expense User"; + CreateExpenseLocation: Codeunit "Create Expense Location"; + ContosoExpenseAgent: Codeunit "Contoso Expense Agent"; + CreateExpCategories: Codeunit "Create Expense Categories DM"; + DKExpCategories: Codeunit "DK Exp. Categories"; + CreateExpenseSubcategories: Codeunit "Create Expense Subcategories"; + CreateExpensePaymentMethod: Codeunit "Create Expense Payment Method"; + begin + ExpenseReportHeader := ContosoExpenseAgent.InsertExpenseReportHeader(CreateExpenseUser.JO(), ContosoUtility.AdjustDate(19021104D), ContosoUtility.AdjustDate(19021104D)); + Expense := ContosoExpenseAgent.InsertExpense(CreateExpenseUser.JO(), DKExpCategories.PerDiem(), CreateExpenseLocation.GermanyAll(), BusinessTripToHamburgLbl, '', ContosoUtility.AdjustDate(19021103D), '', 0, '', CreateExpensePaymentMethod.Cash(), true, false, '', CreateDateTime(ContosoUtility.AdjustDate(19021024D), 064500T), CreateDateTime(ContosoUtility.AdjustDate(19021027D), 161500T), 0, 0, '', '', '', '', ''); + ReleaseAndAddExpenseToExpenseReport(Expense, ExpenseReportHeader); + Expense := ContosoExpenseAgent.InsertExpense(CreateExpenseUser.JO(), CreateExpCategories.Airline(), '', AirlineTicketsLbl, '', ContosoUtility.AdjustDate(19021010D), '', 2042, MargieTravelLbl, CreateExpensePaymentMethod.Card(), true, false, '', 0DT, 0DT, 0, 0, '', '', 'TY6HJO', '', ''); + ReleaseAndAddExpenseToExpenseReport(Expense, ExpenseReportHeader); + + ExpenseReportHeader := ContosoExpenseAgent.InsertExpenseReportHeader(CreateExpenseUser.EH(), ContosoUtility.AdjustDate(19021204D), ContosoUtility.AdjustDate(19021204D)); + Expense := ContosoExpenseAgent.InsertExpense(CreateExpenseUser.EH(), CreateExpCategories.Airline(), '', AirlineTicketsDublinLbl, TravelToConferenceLbl, ContosoUtility.AdjustDate(19021106D), '', 3120, MargieTravelLbl, CreateExpensePaymentMethod.Card(), true, false, '', 0DT, 0DT, 0, 0, '', '', 'FIUXHJT', '', ''); + ReleaseAndAddExpenseToExpenseReport(Expense, ExpenseReportHeader); + Expense := ContosoExpenseAgent.InsertExpense(CreateExpenseUser.EH(), CreateExpCategories.Events(), '', ITConferenceLbl, '', ContosoUtility.AdjustDate(19021107D), CreateCurrency.EUR(), 1990, ProsewareIncLbl, CreateExpensePaymentMethod.Card(), true, false, '', 0DT, 0DT, 0, 0, '', '', 'G574576HJ656', '', ''); + ReleaseAndAddExpenseToExpenseReport(Expense, ExpenseReportHeader); + Expense := ContosoExpenseAgent.InsertExpense(CreateExpenseUser.EH(), CreateExpCategories.GroundTransportation(), '', TaxiLbl, '', ContosoUtility.AdjustDate(19021114D), CreateCurrency.EUR(), 45, TailwindTradersLbl, CreateExpensePaymentMethod.Cash(), true, false, '', 0DT, 0DT, 0, 0, '', '', '456845856867', '', ''); + ReleaseAndAddExpenseToExpenseReport(Expense, ExpenseReportHeader); + Expense := ContosoExpenseAgent.InsertExpense(CreateExpenseUser.EH(), CreateExpCategories.Entertain(), '', BusinessDinnerLbl, BusinessDinnerWithBigPotentialCustomersLbl, ContosoUtility.AdjustDate(19021116D), CreateCurrency.EUR(), 842, FourthCoffeeLbl, CreateExpensePaymentMethod.Card(), true, false, '', 0DT, 0DT, 0, 0, '', '', 'RT6457560034', '', ''); + ContosoExpenseAgent.InsertExpenseParticipant(Expense."No.", 10000, CreateExpCategories.Entertain(), Enum::"Expense Participant Type"::Employee, CreateEmployee.ManagingDirector(), '', '', '', '', ''); + ContosoExpenseAgent.InsertExpenseParticipant(Expense."No.", 20000, CreateExpCategories.Entertain(), Enum::"Expense Participant Type"::Employee, CreateEmployee.SalesManager(), '', '', '', '', ''); + ContosoExpenseAgent.InsertExpenseParticipant(Expense."No.", 30000, CreateExpCategories.Entertain(), Enum::"Expense Participant Type"::External, '', JesseHomerLbl, RelecloudLbl, '', CEOLbl, 'jesse.homer@contoso.com'); + ContosoExpenseAgent.InsertExpenseParticipant(Expense."No.", 40000, CreateExpCategories.Entertain(), Enum::"Expense Participant Type"::External, '', RobertTownesLbl, AdatumCorporationLbl, '', CEOLbl, 'robert.townes@contoso.com'); + ReleaseAndAddExpenseToExpenseReport(Expense, ExpenseReportHeader); + Expense := ContosoExpenseAgent.InsertExpense(CreateExpenseUser.EH(), CreateExpCategories.Hotels(), '', HotelStayLbl, '', ContosoUtility.AdjustDate(19021118D), CreateCurrency.EUR(), 2150, ContosoSuitesLbl, CreateExpensePaymentMethod.Card(), true, false, '', 0DT, 0DT, 0, 0, '', '', '64675S879CT987990004', '', ''); + ContosoExpenseAgent.InsertExpenseItemization(Expense."No.", 10000, CreateExpCategories.Hotels(), CreateExpenseSubcategories.Room(), AccommodationLbl, ContosoUtility.AdjustDate(19021114D), 390); + ContosoExpenseAgent.InsertExpenseItemization(Expense."No.", 20000, CreateExpCategories.Hotels(), CreateExpenseSubcategories.Breakfast(), BreakfastLbl, ContosoUtility.AdjustDate(19021115D), 35); + ContosoExpenseAgent.InsertExpenseItemization(Expense."No.", 30000, CreateExpCategories.Hotels(), CreateExpenseSubcategories.Room(), AccommodationLbl, ContosoUtility.AdjustDate(19021115D), 390); + ContosoExpenseAgent.InsertExpenseItemization(Expense."No.", 40000, CreateExpCategories.Hotels(), CreateExpenseSubcategories.Breakfast(), BreakfastLbl, ContosoUtility.AdjustDate(19021116D), 35); + ContosoExpenseAgent.InsertExpenseItemization(Expense."No.", 50000, CreateExpCategories.Hotels(), CreateExpenseSubcategories.Room(), AccommodationLbl, ContosoUtility.AdjustDate(19021116D), 390); + ContosoExpenseAgent.InsertExpenseItemization(Expense."No.", 60000, CreateExpCategories.Hotels(), CreateExpenseSubcategories.RoomService(), RoomServiceLbl, ContosoUtility.AdjustDate(19021116D), 145); + ContosoExpenseAgent.InsertExpenseItemization(Expense."No.", 70000, CreateExpCategories.Hotels(), CreateExpenseSubcategories.Breakfast(), BreakfastLbl, ContosoUtility.AdjustDate(19021117D), 35); + ContosoExpenseAgent.InsertExpenseItemization(Expense."No.", 80000, CreateExpCategories.Hotels(), CreateExpenseSubcategories.Room(), AccommodationLbl, ContosoUtility.AdjustDate(19021117D), 390); + ContosoExpenseAgent.InsertExpenseItemization(Expense."No.", 90000, CreateExpCategories.Hotels(), CreateExpenseSubcategories.Breakfast(), BreakfastLbl, ContosoUtility.AdjustDate(19021118D), 35); + ContosoExpenseAgent.InsertExpenseItemization(Expense."No.", 100000, CreateExpCategories.Hotels(), CreateExpenseSubcategories.Tax(), HotelTaxesLbl, ContosoUtility.AdjustDate(19021118D), 305); + ReleaseAndAddExpenseToExpenseReport(Expense, ExpenseReportHeader); + Expense := ContosoExpenseAgent.InsertExpense(CreateExpenseUser.EH(), CreateExpCategories.RentalCars(), '', CarRentalsLbl, '', ContosoUtility.AdjustDate(19021118D), CreateCurrency.EUR(), 622.45, VanArsdelLtdLbl, CreateExpensePaymentMethod.Card(), true, false, '', 0DT, 0DT, 0, 0, '', '', 'H6584769867J9J95789', '', ''); + ReleaseAndAddExpenseToExpenseReport(Expense, ExpenseReportHeader); + Expense := ContosoExpenseAgent.InsertExpense(CreateExpenseUser.EH(), CreateExpCategories.GroundTransportation(), '', TaxiLbl, '', ContosoUtility.AdjustDate(19021118D), CreateCurrency.EUR(), 71, TailwindTradersLbl, CreateExpensePaymentMethod.Cash(), true, false, '', 0DT, 0DT, 0, 0, '', '', '7456875687568', '', ''); + ReleaseAndAddExpenseToExpenseReport(Expense, ExpenseReportHeader); + Expense := ContosoExpenseAgent.InsertExpense(CreateExpenseUser.EH(), DKExpCategories.PerDiem(), CreateExpenseLocation.UKOther(), TripToUKLbl, '', ContosoUtility.AdjustDate(19021121D), '', 0, '', CreateExpensePaymentMethod.Cash(), true, false, '', CreateDateTime(ContosoUtility.AdjustDate(19021114D), 053000T), CreateDateTime(ContosoUtility.AdjustDate(19021118D), 220500T), 0, 0, '', '', '', '', ''); + UpdateExpensePerDiem(Expense."No.", 20000, false, false, true); + UpdateExpensePerDiem(Expense."No.", 40000, false, true, false); + ReleaseAndAddExpenseToExpenseReport(Expense, ExpenseReportHeader); + Expense := ContosoExpenseAgent.InsertExpense(CreateExpenseUser.EH(), DKExpCategories.PerDiem(), CreateExpenseLocation.Domestic(), TripToDoverLbl, '', ContosoUtility.AdjustDate(19021204D), '', 0, '', CreateExpensePaymentMethod.Cash(), true, false, '', CreateDateTime(ContosoUtility.AdjustDate(19021127D), 070000T), CreateDateTime(ContosoUtility.AdjustDate(19021129D), 145500T), 0, 0, '', '', '', '', ''); + ReleaseAndAddExpenseToExpenseReport(Expense, ExpenseReportHeader); + Expense := ContosoExpenseAgent.InsertExpense(CreateExpenseUser.EH(), CreateExpCategories.Mileage(), '', MileageLbl, '', ContosoUtility.AdjustDate(19031101D), '', 0, VanArsdelLtdLbl, CreateExpensePaymentMethod.Cash(), true, false, '', 0DT, 0DT, 0, 249, 'New York', 'Dover', 'H6584769867J9J95789', '', ''); + ReleaseAndAddExpenseToExpenseReport(Expense, ExpenseReportHeader); + end; + + var + FromExpenseReportNo: Code[20]; + BusinessTripToHamburgLbl: Label 'Business trip to Hamburg, DE', MaxLength = 100; + AirlineTicketsLbl: Label 'Airline tickets NY/FRANKFURT/HAMBURG/FRANKFURT/NY', MaxLength = 100; + MargieTravelLbl: Label 'Margie''s Travel', MaxLength = 100; + AirlineTicketsDublinLbl: Label 'Airline tickets NY/DUBLIN/NY', MaxLength = 100; + TravelToConferenceLbl: Label 'Travel to the conference', MaxLength = 100; + ITConferenceLbl: Label 'IT Conference', MaxLength = 100; + ProsewareIncLbl: Label 'Proseware, Inc.', MaxLength = 100; + TaxiLbl: Label 'Taxi', MaxLength = 100; + TailwindTradersLbl: Label 'Tailwind Traders', MaxLength = 100; + BusinessDinnerLbl: Label 'Business Dinner', MaxLength = 100; + BusinessDinnerWithBigPotentialCustomersLbl: Label 'Business dinner with a big potential customers', MaxLength = 100; + FourthCoffeeLbl: Label 'Fourth Coffee', MaxLength = 100; + JesseHomerLbl: Label 'Jesse Homer', MaxLength = 100; + RelecloudLbl: Label 'Relecloud', MaxLength = 100; + RobertTownesLbl: Label 'Robert Townes', MaxLength = 100; + AdatumCorporationLbl: Label 'Adatum Corporation', MaxLength = 100; + HotelStayLbl: Label 'Hotel stay', MaxLength = 100; + ContosoSuitesLbl: Label 'Contoso Suites', MaxLength = 100; + AccommodationLbl: Label 'Accommodation', MaxLength = 100; + BreakfastLbl: Label 'Breakfast', MaxLength = 100; + HotelTaxesLbl: Label 'Hotel Taxes', MaxLength = 100; + RoomServiceLbl: Label 'Room service', MaxLength = 100; + CarRentalsLbl: Label 'Car Rentals', MaxLength = 100; + VanArsdelLtdLbl: Label 'VanArsdel, Ltd.', MaxLength = 100; + TripToUKLbl: Label 'Trip to UK', MaxLength = 100; + TripToDoverLbl: Label 'Trip to Dover', MaxLength = 100; + MileageLbl: Label 'Mileage', MaxLength = 100; + CEOLbl: Label 'CEO', MaxLength = 30; + + local procedure ReleaseAndAddExpenseToExpenseReport(Expense: Record Expense; ExpenseReportHeader: Record "Expense Report Header") + var + ReleaseExpenseDocument: Codeunit "Release Expense Document"; + CreateExpenseReport: Codeunit "Create Expense Report"; + begin + Expense.Get(Expense."No."); + ReleaseExpenseDocument.Run(Expense); + + CreateExpenseReport.AddSingleExpenseToExpenseReport(Expense, ExpenseReportHeader); + end; + + local procedure PostExpenseReport() + var + ExpenseReportHeader: Record "Expense Report Header"; + begin + if FromExpenseReportNo <> '' then + ExpenseReportHeader.SetFilter("No.", '>%1', FromExpenseReportNo); + + if ExpenseReportHeader.FindSet() then + repeat + Codeunit.Run(Codeunit::"Expense Report-Post", ExpenseReportHeader); + until ExpenseReportHeader.Next() = 0; + end; + + local procedure UpdateExpensePerDiem(ExpenseNo: Code[20]; LineNo: Integer; Breakfast: Boolean; Lunch: Boolean; Dinner: Boolean) + var + ExpensePerDiem: Record "Expense Per Diem"; + begin + ExpensePerDiem.Get(ExpenseNo, LineNo); + + ExpensePerDiem.Validate(Breakfast, Breakfast); + ExpensePerDiem.Validate(Lunch, Lunch); + ExpensePerDiem.Validate(Dinner, Dinner); + ExpensePerDiem.Modify(); + end; +} diff --git a/src/Apps/W1/ExpenseAgent/demo data/Country/DK/DKUpdEmpPostingGrp.Codeunit.al b/src/Apps/W1/ExpenseAgent/demo data/Country/DK/DKUpdEmpPostingGrp.Codeunit.al new file mode 100644 index 00000000000..06a0528020e --- /dev/null +++ b/src/Apps/W1/ExpenseAgent/demo data/Country/DK/DKUpdEmpPostingGrp.Codeunit.al @@ -0,0 +1,30 @@ +// ------------------------------------------------------------------------------------------------ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. See License.txt in the project root for license information. +// ------------------------------------------------------------------------------------------------ +namespace Microsoft.ExpenseAgent; +using Microsoft.DemoData.HumanResources; + +codeunit 8292 "DK Upd. Emp. Posting Grp" +{ + InherentEntitlements = X; + InherentPermissions = X; + + trigger OnRun() + begin + UpdateEmployeePostingGroup(); + end; + + local procedure UpdateEmployeePostingGroup() + var + ExpenseGLAccount: Codeunit "Create Expense G/L Account"; + DKExpGLAccount: Codeunit "DK Exp. GL Account"; + DKGLAccountNames: Codeunit "DK GL Account Names"; + ContosoExpenseAgent: Codeunit "Contoso Expense Agent"; + CreateEmployeePostingGroup: Codeunit "Create Employee Posting Group"; + begin + ContosoExpenseAgent.SetOverwriteData(true); + ContosoExpenseAgent.UpdateEmployeePostingGroup(CreateEmployeePostingGroup.EmployeeExpenses(), ExpenseGLAccount.FindGLAccountByName(DKGLAccountNames.AccountsPayablePostingName()), ExpenseGLAccount.FindGLAccountByName(DKGLAccountNames.PrepaymentsAccruedCostsName()), ExpenseGLAccount.FindGLAccountByName(DKGLAccountNames.BankName()), DKExpGLAccount.CompanyCreditCards()); + ContosoExpenseAgent.SetOverwriteData(false); + end; +} diff --git a/src/Apps/W1/ExpenseAgent/demo data/Country/ES/ESCountryData.Codeunit.al b/src/Apps/W1/ExpenseAgent/demo data/Country/ES/ESCountryData.Codeunit.al new file mode 100644 index 00000000000..b7bc8b66c76 --- /dev/null +++ b/src/Apps/W1/ExpenseAgent/demo data/Country/ES/ESCountryData.Codeunit.al @@ -0,0 +1,70 @@ +// ------------------------------------------------------------------------------------------------ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. See License.txt in the project root for license information. +// ------------------------------------------------------------------------------------------------ +namespace Microsoft.ExpenseAgent; + +codeunit 8275 "ES Country Data" implements "Expense Agent Country Data" +{ + Access = Internal; + InherentEntitlements = X; + InherentPermissions = X; + + procedure CreateSetupData() + var + W1CountryData: Codeunit "W1 Country Data"; + ESExpGLAccount: Codeunit "ES Exp. GL Account"; + ESExpPostingGrp: Codeunit "ES Exp. Posting Grp"; + begin + BindSubscription(ESExpGLAccount); + BindSubscription(ESExpPostingGrp); + + W1CountryData.CreateSetupData(); + Codeunit.Run(Codeunit::"ES Upd. Employee"); + Codeunit.Run(Codeunit::"ES Upd. Emp. Posting Grp"); + Codeunit.Run(Codeunit::"ES Exp. Posting Grp"); + + UnbindSubscription(ESExpPostingGrp); + UnbindSubscription(ESExpGLAccount); + end; + + procedure CreateMasterData() + var + W1CountryData: Codeunit "W1 Country Data"; + begin + W1CountryData.CreateMasterData(); + Codeunit.Run(Codeunit::"ES Exp. Categories"); + Codeunit.Run(Codeunit::"ES Exp. SubCategories"); + Codeunit.Run(Codeunit::"ES Exp. Rule Header"); + Codeunit.Run(Codeunit::"ES Exp. Rule Condition"); + end; + + procedure CreateTransactionalData() + var + W1CountryData: Codeunit "W1 Country Data"; + ESCurrencySwapSub: Codeunit "ES Currency Swap Sub"; + begin + BindSubscription(ESCurrencySwapSub); + + W1CountryData.CreateTransactionalData(); + Codeunit.Run(Codeunit::"ES Expense"); + + UnbindSubscription(ESCurrencySwapSub); + end; + + procedure CreateHistoricalData() + var + W1CountryData: Codeunit "W1 Country Data"; + ESCurrencySwapSub: Codeunit "ES Currency Swap Sub"; + ESPostedExpReport: Codeunit "ES Posted Exp. Report"; + begin + BindSubscription(ESCurrencySwapSub); + BindSubscription(ESPostedExpReport); + + W1CountryData.CreateHistoricalData(); + Codeunit.Run(Codeunit::"ES Posted Exp. Report"); + + UnbindSubscription(ESPostedExpReport); + UnbindSubscription(ESCurrencySwapSub); + end; +} diff --git a/src/Apps/W1/ExpenseAgent/demo data/Country/ES/ESCurrencySwapSub.Codeunit.al b/src/Apps/W1/ExpenseAgent/demo data/Country/ES/ESCurrencySwapSub.Codeunit.al new file mode 100644 index 00000000000..2b698862020 --- /dev/null +++ b/src/Apps/W1/ExpenseAgent/demo data/Country/ES/ESCurrencySwapSub.Codeunit.al @@ -0,0 +1,24 @@ +// ------------------------------------------------------------------------------------------------ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. See License.txt in the project root for license information. +// ------------------------------------------------------------------------------------------------ +namespace Microsoft.ExpenseAgent; + +using Microsoft.DemoData.Finance; + +codeunit 8287 "ES Currency Swap Sub" +{ + SingleInstance = true; + EventSubscriberInstance = Manual; + InherentEntitlements = X; + InherentPermissions = X; + + [EventSubscriber(ObjectType::Codeunit, Codeunit::"Contoso Expense Agent", OnBeforeValidateCurrencyCodeInExpense, '', false, false)] + local procedure OnBeforeValidateCurrencyCodeInExpense(var CurrencyCode: Code[10]) + var + CreateCurrency: Codeunit "Create Currency"; + begin + if CurrencyCode = CreateCurrency.EUR() then + CurrencyCode := CreateCurrency.USD(); + end; +} diff --git a/src/Apps/W1/ExpenseAgent/demo data/Country/ES/ESExpCategories.Codeunit.al b/src/Apps/W1/ExpenseAgent/demo data/Country/ES/ESExpCategories.Codeunit.al new file mode 100644 index 00000000000..f1488f5c145 --- /dev/null +++ b/src/Apps/W1/ExpenseAgent/demo data/Country/ES/ESExpCategories.Codeunit.al @@ -0,0 +1,31 @@ +// ------------------------------------------------------------------------------------------------ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. See License.txt in the project root for license information. +// ------------------------------------------------------------------------------------------------ +namespace Microsoft.ExpenseAgent; + +codeunit 8280 "ES Exp. Categories" +{ + InherentEntitlements = X; + InherentPermissions = X; + + trigger OnRun() + var + CreateExpenseGroup: Codeunit "Create Expense Group"; + CreateExpensePaymentMethod: Codeunit "Create Expense Payment Method"; + ContosoExpenseAgent: Codeunit "Contoso Expense Agent"; + ESExpPostingGrp: Codeunit "ES Exp. Posting Grp"; + begin + ContosoExpenseAgent.InsertExpenseCategory(PerDiem(), PerDiemByAssignedPolicyLbl, PerDiemByAssignedPolicyPostingLbl, ESExpPostingGrp.ExpensePerDiem(), Enum::"Expense Attachment Enforcement"::" ", CreateExpensePaymentMethod.Cash(), false, false, CreateExpenseGroup.Travel(), true, Enum::"Expense Reimbursement Type"::"Employee Paid", Enum::"Expense Detail Needed"::"Per Diem"); + end; + + var + PerDiemTok: Label 'PER-DIEM', MaxLength = 20, Locked = true; + PerDiemByAssignedPolicyLbl: Label 'Expenses for per-diem or daily allowance paid for business trips, typically based on travel itinerary or other proof of travel (e.g., booking or agenda), rather than individual expense receipts.', MaxLength = 250; + PerDiemByAssignedPolicyPostingLbl: Label 'Per-diem by assigned policy', MaxLength = 100; + + procedure PerDiem(): Code[20] + begin + exit(PerDiemTok); + end; +} diff --git a/src/Apps/W1/ExpenseAgent/demo data/Country/ES/ESExpGLAccount.Codeunit.al b/src/Apps/W1/ExpenseAgent/demo data/Country/ES/ESExpGLAccount.Codeunit.al new file mode 100644 index 00000000000..2663aacaebb --- /dev/null +++ b/src/Apps/W1/ExpenseAgent/demo data/Country/ES/ESExpGLAccount.Codeunit.al @@ -0,0 +1,168 @@ +// ------------------------------------------------------------------------------------------------ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. See License.txt in the project root for license information. +// ------------------------------------------------------------------------------------------------ +namespace Microsoft.ExpenseAgent; + +using Microsoft.DemoTool.Helpers; +using Microsoft.Finance.GeneralLedger.Account; +using Microsoft.Foundation.Enums; + +codeunit 8277 "ES Exp. GL Account" +{ + SingleInstance = true; + EventSubscriberInstance = Manual; + InherentEntitlements = X; + InherentPermissions = X; + + [EventSubscriber(ObjectType::Codeunit, Codeunit::"Create Expense G/L Account", 'OnAfterAddGLAccountsForLocalization', '', false, false)] + local procedure ModifyGLAccount() + var + GLAccountCategory: Record "G/L Account Category"; + SubCategory: Text[80]; + begin + AddGLAccounts(); + + SubCategory := Format(GLAccountCategory."Account Category"::Assets, 80); + ContosoGLAccount.InsertGLAccount(CompanyCreditCardsClearingAccount(), CompanyCreditCardsClearingAccountName(), "G/L Account Income/Balance"::"Balance Sheet", Enum::"G/L Account Category"::Assets, SubCategory, Enum::"G/L Account Type"::Posting, '', '', '', 0, '', Enum::"General Posting Type"::" ", '', '', true, false, false); + ContosoGLAccount.InsertGLAccount(ExpensesPrepayments(), ExpensesPrepaymentsName(), "G/L Account Income/Balance"::"Balance Sheet", Enum::"G/L Account Category"::Assets, SubCategory, Enum::"G/L Account Type"::Posting, '', '', '', 0, '', Enum::"General Posting Type"::" ", '', '', true, false, false); + + SubCategory := Format(GLAccountCategory."Account Category"::Expense, 80); + ContosoGLAccount.InsertGLAccount(ExpenseGLAccount.PerDiemTravelExpensesAccount(), ExpenseGLAccount.PerDiemTravelExpensesAccountName(), "G/L Account Income/Balance"::"Income Statement", Enum::"G/L Account Category"::Expense, SubCategory, Enum::"G/L Account Type"::Posting, '', '', '', 0, '', Enum::"General Posting Type"::Purchase, '', '', true, false, false); + ContosoGLAccount.InsertGLAccount(ExpenseGLAccount.MileageTravelExpensesAccount(), ExpenseGLAccount.MileageTravelExpensesAccountName(), "G/L Account Income/Balance"::"Income Statement", Enum::"G/L Account Category"::Expense, SubCategory, Enum::"G/L Account Type"::Posting, '', '', '', 0, '', Enum::"General Posting Type"::Purchase, '', '', true, false, false); + ContosoGLAccount.InsertGLAccount(ExpenseGLAccount.MealExpensesDeductibleAccount(), ExpenseGLAccount.MealExpensesDeductibleAccountName(), "G/L Account Income/Balance"::"Income Statement", Enum::"G/L Account Category"::Expense, SubCategory, Enum::"G/L Account Type"::Posting, '', '', '', 0, '', Enum::"General Posting Type"::Purchase, '', '', true, false, false); + ContosoGLAccount.InsertGLAccount(ExpenseGLAccount.MealExpensesNondeductibleAccount(), ExpenseGLAccount.MealExpensesNondeductibleAccountName(), "G/L Account Income/Balance"::"Income Statement", Enum::"G/L Account Category"::Expense, SubCategory, Enum::"G/L Account Type"::Posting, '', '', '', 0, '', Enum::"General Posting Type"::Purchase, '', '', true, false, false); + ContosoGLAccount.InsertGLAccount(ExpenseGLAccount.OtherNondeductibleTravelExpensesAccount(), ExpenseGLAccount.OtherNondeductibleTravelExpensesAccountName(), "G/L Account Income/Balance"::"Income Statement", Enum::"G/L Account Category"::Expense, SubCategory, Enum::"G/L Account Type"::Posting, '', '', '', 0, '', Enum::"General Posting Type"::Purchase, '', '', true, false, false); + ContosoGLAccount.InsertGLAccount(RentalCarExpenses(), RentalCarExpensesName(), "G/L Account Income/Balance"::"Income Statement", Enum::"G/L Account Category"::Expense, SubCategory, Enum::"G/L Account Type"::Posting, '', '', '', 0, '', Enum::"General Posting Type"::Purchase, '', '', true, false, false); + ContosoGLAccount.InsertGLAccount(TravelExpenses(), TravelExpensesName(), "G/L Account Income/Balance"::"Income Statement", Enum::"G/L Account Category"::Expense, SubCategory, Enum::"G/L Account Type"::Posting, '', '', '', 0, '', Enum::"General Posting Type"::Purchase, '', '', true, false, false); + ContosoGLAccount.InsertGLAccount(EntertainmentExpensesAccount(), EntertainmentExpensesAccountName(), "G/L Account Income/Balance"::"Income Statement", Enum::"G/L Account Category"::Expense, SubCategory, Enum::"G/L Account Type"::Posting, '', '', '', 0, '', Enum::"General Posting Type"::Purchase, '', '', true, false, false); + ContosoGLAccount.InsertGLAccount(RoundingExpensesOperatingAccount(), RoundingExpensesOperatingAccountName(), "G/L Account Income/Balance"::"Income Statement", Enum::"G/L Account Category"::Expense, SubCategory, Enum::"G/L Account Type"::Posting, '', '', '', 0, '', Enum::"General Posting Type"::Purchase, '', '', true, false, false); + + UpdateIncomeStatementBalanceAccount(); + end; + + local procedure AddGLAccounts() + begin + ContosoGLAccount.AddAccountForLocalization(CompanyCreditCardsClearingAccountName(), '5721001'); + ContosoGLAccount.AddAccountForLocalization(ExpensesPrepaymentsName(), '4800001'); + ContosoGLAccount.AddAccountForLocalization(ExpenseGLAccount.PerDiemTravelExpensesAccountName(), '6291002'); + ContosoGLAccount.AddAccountForLocalization(ExpenseGLAccount.MileageTravelExpensesAccountName(), '6291003'); + ContosoGLAccount.AddAccountForLocalization(ExpenseGLAccount.MealExpensesDeductibleAccountName(), '6292001'); + ContosoGLAccount.AddAccountForLocalization(ExpenseGLAccount.MealExpensesNondeductibleAccountName(), '6292002'); + ContosoGLAccount.AddAccountForLocalization(ExpenseGLAccount.OtherNondeductibleTravelExpensesAccountName(), '6299001'); + ContosoGLAccount.AddAccountForLocalization(RentalCarExpensesName(), '6291004'); + ContosoGLAccount.AddAccountForLocalization(TravelExpensesName(), '6291001'); + ContosoGLAccount.AddAccountForLocalization(EntertainmentExpensesAccountName(), '6293001'); + ContosoGLAccount.AddAccountForLocalization(RoundingExpensesOperatingAccountName(), '6298001'); + end; + + local procedure UpdateIncomeStatementBalanceAccount() + begin + UpdateIncomeStmtBalAcc(CompanyCreditCardsClearingAccount(), ExpenseGLAccount.FindGLAccountByName(ESGLAccountNames.ProfitOrLossName())); + UpdateIncomeStmtBalAcc(ExpensesPrepayments(), ExpenseGLAccount.FindGLAccountByName(ESGLAccountNames.ProfitOrLossName())); + UpdateIncomeStmtBalAcc(ExpenseGLAccount.PerDiemTravelExpensesAccount(), ExpenseGLAccount.FindGLAccountByName(ESGLAccountNames.ProfitOrLossName())); + UpdateIncomeStmtBalAcc(ExpenseGLAccount.MileageTravelExpensesAccount(), ExpenseGLAccount.FindGLAccountByName(ESGLAccountNames.ProfitOrLossName())); + UpdateIncomeStmtBalAcc(ExpenseGLAccount.MealExpensesDeductibleAccount(), ExpenseGLAccount.FindGLAccountByName(ESGLAccountNames.ProfitOrLossName())); + UpdateIncomeStmtBalAcc(ExpenseGLAccount.MealExpensesNondeductibleAccount(), ExpenseGLAccount.FindGLAccountByName(ESGLAccountNames.ProfitOrLossName())); + UpdateIncomeStmtBalAcc(ExpenseGLAccount.OtherNondeductibleTravelExpensesAccount(), ExpenseGLAccount.FindGLAccountByName(ESGLAccountNames.ProfitOrLossName())); + UpdateIncomeStmtBalAcc(RentalCarExpenses(), ExpenseGLAccount.FindGLAccountByName(ESGLAccountNames.ProfitOrLossName())); + UpdateIncomeStmtBalAcc(TravelExpenses(), ExpenseGLAccount.FindGLAccountByName(ESGLAccountNames.ProfitOrLossName())); + UpdateIncomeStmtBalAcc(EntertainmentExpensesAccount(), ExpenseGLAccount.FindGLAccountByName(ESGLAccountNames.ProfitOrLossName())); + UpdateIncomeStmtBalAcc(RoundingExpensesOperatingAccount(), ExpenseGLAccount.FindGLAccountByName(ESGLAccountNames.ProfitOrLossName())); + end; + + local procedure UpdateIncomeStmtBalAcc(No: Code[20]; IncomeStmtBalAcc: Code[20]) + var + GLAccount: Record "G/L Account"; + RecRef: RecordRef; + FieldRef: FieldRef; + i: Integer; + begin + // "Income Stmt. Bal. Acc." is added by the ES localization to table G/L Account. + // Look it up dynamically via FieldRef so this demo data works without an ES-loc + // compile-time dependency; silently skip when the field is not present. + if not GLAccount.Get(No) then + exit; + + RecRef.GetTable(GLAccount); + for i := 1 to RecRef.FieldCount do begin + FieldRef := RecRef.FieldIndex(i); + if FieldRef.Name = 'Income Stmt. Bal. Acc.' then begin + FieldRef.Validate(IncomeStmtBalAcc); + RecRef.Modify(); + exit; + end; + end; + end; + + var + ContosoGLAccount: Codeunit "Contoso GL Account"; + ExpenseGLAccount: Codeunit "Create Expense G/L Account"; + ESGLAccountNames: Codeunit "ES GL Account Names"; + CompanyCreditCardsClearingAccountTok: Label 'Company credit card clearing account', MaxLength = 100; + TravelExpensesTok: Label 'Travel expenses', MaxLength = 100; + ExpensesPrepaymentsTok: Label 'Expenses Prepayments', MaxLength = 100; + RentalCarExpensesTok: Label 'Rental Car Expenses', MaxLength = 100; + EntertainmentExpensesTok: Label 'Entertainment expenses', MaxLength = 100; + RoundingExpensesOperatingTok: Label 'Rounding Expenses (Operating)', MaxLength = 100; + + procedure CompanyCreditCardsClearingAccount(): Code[20] + begin + exit(ContosoGLAccount.GetAccountNo(CompanyCreditCardsClearingAccountName())); + end; + + procedure CompanyCreditCardsClearingAccountName(): Text[100] + begin + exit(CompanyCreditCardsClearingAccountTok); + end; + + procedure TravelExpenses(): Code[20] + begin + exit(ContosoGLAccount.GetAccountNo(TravelExpensesName())); + end; + + procedure TravelExpensesName(): Text[100] + begin + exit(TravelExpensesTok); + end; + + procedure ExpensesPrepayments(): Code[20] + begin + exit(ContosoGLAccount.GetAccountNo(ExpensesPrepaymentsName())); + end; + + procedure ExpensesPrepaymentsName(): Text[100] + begin + exit(ExpensesPrepaymentsTok); + end; + + procedure RentalCarExpenses(): Code[20] + begin + exit(ContosoGLAccount.GetAccountNo(RentalCarExpensesName())); + end; + + procedure RentalCarExpensesName(): Text[100] + begin + exit(RentalCarExpensesTok); + end; + + procedure EntertainmentExpensesAccount(): Code[20] + begin + exit(ContosoGLAccount.GetAccountNo(EntertainmentExpensesAccountName())); + end; + + procedure EntertainmentExpensesAccountName(): Text[100] + begin + exit(EntertainmentExpensesTok); + end; + + procedure RoundingExpensesOperatingAccount(): Code[20] + begin + exit(ContosoGLAccount.GetAccountNo(RoundingExpensesOperatingAccountName())); + end; + + procedure RoundingExpensesOperatingAccountName(): Text[100] + begin + exit(RoundingExpensesOperatingTok); + end; +} diff --git a/src/Apps/W1/ExpenseAgent/demo data/Country/ES/ESExpPostingGrp.Codeunit.al b/src/Apps/W1/ExpenseAgent/demo data/Country/ES/ESExpPostingGrp.Codeunit.al new file mode 100644 index 00000000000..e7fd2ba3e9f --- /dev/null +++ b/src/Apps/W1/ExpenseAgent/demo data/Country/ES/ESExpPostingGrp.Codeunit.al @@ -0,0 +1,65 @@ +// ------------------------------------------------------------------------------------------------ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. See License.txt in the project root for license information. +// ------------------------------------------------------------------------------------------------ +namespace Microsoft.ExpenseAgent; + + +codeunit 8278 "ES Exp. Posting Grp" +{ + SingleInstance = true; + EventSubscriberInstance = Manual; + InherentEntitlements = X; + InherentPermissions = X; + + trigger OnRun() + var + ContosoExpenseAgent: Codeunit "Contoso Expense Agent"; + begin + ContosoExpenseAgent.InsertExpensePostingGroup(ExpensePerDiem(), ExpensePerDiemLbl); + end; + + [EventSubscriber(ObjectType::Table, Database::"Expense Posting Group", 'OnBeforeInsertEvent', '', false, false)] + local procedure OnInsertRecord(var Rec: Record "Expense Posting Group") + var + ExpenseGLAccount: Codeunit "Create Expense G/L Account"; + ESExpGLAccount: Codeunit "ES Exp. GL Account"; + ESGLAccountNames: Codeunit "ES GL Account Names"; + CreateExpensePostingGroup: Codeunit "Create Expense Posting Group"; + begin + case Rec.Code of + CreateExpensePostingGroup.ExpenseEntertainment(): + ValidateRecordFields(Rec, ESExpGLAccount.EntertainmentExpensesAccount(), '', ESExpGLAccount.ExpensesPrepayments(), ESExpGLAccount.RoundingExpensesOperatingAccount(), ESExpGLAccount.RoundingExpensesOperatingAccount()); + CreateExpensePostingGroup.ExpenseMeals(): + ValidateRecordFields(Rec, ExpenseGLAccount.MealExpensesDeductibleAccount(), ExpenseGLAccount.MealExpensesNondeductibleAccount(), ESExpGLAccount.ExpensesPrepayments(), ESExpGLAccount.RoundingExpensesOperatingAccount(), ESExpGLAccount.RoundingExpensesOperatingAccount()); + CreateExpensePostingGroup.ExpenseMileage(): + ValidateRecordFields(Rec, ExpenseGLAccount.MileageTravelExpensesAccount(), '', ESExpGLAccount.ExpensesPrepayments(), ESExpGLAccount.RoundingExpensesOperatingAccount(), ESExpGLAccount.RoundingExpensesOperatingAccount()); + CreateExpensePostingGroup.ExpenseOther(): + ValidateRecordFields(Rec, ExpenseGLAccount.FindGLAccountByName(ESGLAccountNames.OtherBusinessExpensesName()), ExpenseGLAccount.OtherNondeductibleTravelExpensesAccount(), ESExpGLAccount.ExpensesPrepayments(), ESExpGLAccount.RoundingExpensesOperatingAccount(), ESExpGLAccount.RoundingExpensesOperatingAccount()); + ExpensePerDiem(): + ValidateRecordFields(Rec, ExpenseGLAccount.PerDiemTravelExpensesAccount(), '', ESExpGLAccount.ExpensesPrepayments(), ESExpGLAccount.RoundingExpensesOperatingAccount(), ESExpGLAccount.RoundingExpensesOperatingAccount()); + CreateExpensePostingGroup.ExpenseTravel(): + ValidateRecordFields(Rec, ESExpGLAccount.TravelExpenses(), ExpenseGLAccount.OtherNondeductibleTravelExpensesAccount(), ESExpGLAccount.ExpensesPrepayments(), ESExpGLAccount.RoundingExpensesOperatingAccount(), ESExpGLAccount.RoundingExpensesOperatingAccount()); + CreateExpensePostingGroup.ExpenseRentalCars(): + ValidateRecordFields(Rec, ESExpGLAccount.RentalCarExpenses(), '', ESExpGLAccount.ExpensesPrepayments(), ESExpGLAccount.RoundingExpensesOperatingAccount(), ESExpGLAccount.RoundingExpensesOperatingAccount()); + end; + end; + + local procedure ValidateRecordFields(var ExpensePostingGroup: Record "Expense Posting Group"; RefundableDebitAccount: Code[20]; NonRefundableDebitAccount: Code[20]; PrepaymentCreditAccount: Code[20]; ExpenseDebitRoundingAccount: Code[20]; ExpenseCreditRoundingAccount: Code[20]) + begin + ExpensePostingGroup.Validate("Refundable Debit Account", RefundableDebitAccount); + ExpensePostingGroup.Validate("Non-Refundable Debit Account", NonRefundableDebitAccount); + ExpensePostingGroup.Validate("Prepayment Credit Account", PrepaymentCreditAccount); + ExpensePostingGroup.Validate("Debit Rounding Account", ExpenseDebitRoundingAccount); + ExpensePostingGroup.Validate("Credit Rounding Account", ExpenseCreditRoundingAccount); + end; + + var + ExpensePERDIEMTok: Label 'EXPENSE-PERDIEM', MaxLength = 20, Locked = true; + ExpensePerDiemLbl: Label 'Expense - Per Diem', MaxLength = 100; + + procedure ExpensePerDiem(): Code[20] + begin + exit(ExpensePERDIEMTok); + end; +} diff --git a/src/Apps/W1/ExpenseAgent/demo data/Country/ES/ESExpRuleCondition.Codeunit.al b/src/Apps/W1/ExpenseAgent/demo data/Country/ES/ESExpRuleCondition.Codeunit.al new file mode 100644 index 00000000000..dadd21d2422 --- /dev/null +++ b/src/Apps/W1/ExpenseAgent/demo data/Country/ES/ESExpRuleCondition.Codeunit.al @@ -0,0 +1,26 @@ +// ------------------------------------------------------------------------------------------------ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. See License.txt in the project root for license information. +// ------------------------------------------------------------------------------------------------ +namespace Microsoft.ExpenseAgent; + +codeunit 8283 "ES Exp. Rule Condition" +{ + InherentEntitlements = X; + InherentPermissions = X; + + trigger OnRun() + var + ESExpCategories: Codeunit "ES Exp. Categories"; + CreateExpenseLocation: Codeunit "Create Expense Location"; + ContosoExpenseAgent: Codeunit "Contoso Expense Agent"; + begin + ContosoExpenseAgent.InsertExpenseRuleCondition(ESExpCategories.PerDiem(), CreateExpenseLocation.CanadaAll(), 0D, 10000, Enum::"Expense Rule Condition Type"::"Daily Rate", 125); + ContosoExpenseAgent.InsertExpenseRuleCondition(ESExpCategories.PerDiem(), CreateExpenseLocation.DenmarkAll(), 0D, 10000, Enum::"Expense Rule Condition Type"::"Daily Rate", 450); + ContosoExpenseAgent.InsertExpenseRuleCondition(ESExpCategories.PerDiem(), CreateExpenseLocation.Domestic(), 0D, 10000, Enum::"Expense Rule Condition Type"::"Daily Rate", 50); + ContosoExpenseAgent.InsertExpenseRuleCondition(ESExpCategories.PerDiem(), CreateExpenseLocation.FranceAll(), 0D, 10000, Enum::"Expense Rule Condition Type"::"Daily Rate", 110); + ContosoExpenseAgent.InsertExpenseRuleCondition(ESExpCategories.PerDiem(), CreateExpenseLocation.GermanyAll(), 0D, 10000, Enum::"Expense Rule Condition Type"::"Daily Rate", 105); + ContosoExpenseAgent.InsertExpenseRuleCondition(ESExpCategories.PerDiem(), CreateExpenseLocation.UKOther(), 0D, 10000, Enum::"Expense Rule Condition Type"::"Daily Rate", 115); + ContosoExpenseAgent.InsertExpenseRuleCondition(ESExpCategories.PerDiem(), CreateExpenseLocation.USAOther(), 0D, 10000, Enum::"Expense Rule Condition Type"::"Daily Rate", 120); + end; +} diff --git a/src/Apps/W1/ExpenseAgent/demo data/Country/ES/ESExpRuleHeader.Codeunit.al b/src/Apps/W1/ExpenseAgent/demo data/Country/ES/ESExpRuleHeader.Codeunit.al new file mode 100644 index 00000000000..66a12401f7b --- /dev/null +++ b/src/Apps/W1/ExpenseAgent/demo data/Country/ES/ESExpRuleHeader.Codeunit.al @@ -0,0 +1,29 @@ +// ------------------------------------------------------------------------------------------------ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. See License.txt in the project root for license information. +// ------------------------------------------------------------------------------------------------ +namespace Microsoft.ExpenseAgent; + +using Microsoft.DemoData.Finance; + +codeunit 8282 "ES Exp. Rule Header" +{ + InherentEntitlements = X; + InherentPermissions = X; + + trigger OnRun() + var + CreateCurrency: Codeunit "Create Currency"; + ESExpCategories: Codeunit "ES Exp. Categories"; + CreateExpenseLocation: Codeunit "Create Expense Location"; + ContosoExpenseAgent: Codeunit "Contoso Expense Agent"; + begin + ContosoExpenseAgent.InsertExpenseRuleHeader(ESExpCategories.PerDiem(), CreateExpenseLocation.CanadaAll(), 0D, Enum::"Expense Justification"::" ", false, '', CreateCurrency.CAD(), ''); + ContosoExpenseAgent.InsertExpenseRuleHeader(ESExpCategories.PerDiem(), CreateExpenseLocation.DenmarkAll(), 0D, Enum::"Expense Justification"::" ", false, '', CreateCurrency.USD(), ''); + ContosoExpenseAgent.InsertExpenseRuleHeader(ESExpCategories.PerDiem(), CreateExpenseLocation.Domestic(), 0D, Enum::"Expense Justification"::" ", false, '', '', ''); + ContosoExpenseAgent.InsertExpenseRuleHeader(ESExpCategories.PerDiem(), CreateExpenseLocation.FranceAll(), 0D, Enum::"Expense Justification"::" ", false, '', CreateCurrency.USD(), ''); + ContosoExpenseAgent.InsertExpenseRuleHeader(ESExpCategories.PerDiem(), CreateExpenseLocation.GermanyAll(), 0D, Enum::"Expense Justification"::" ", false, '', CreateCurrency.USD(), ''); + ContosoExpenseAgent.InsertExpenseRuleHeader(ESExpCategories.PerDiem(), CreateExpenseLocation.UKOther(), 0D, Enum::"Expense Justification"::" ", false, '', CreateCurrency.GBP(), ''); + ContosoExpenseAgent.InsertExpenseRuleHeader(ESExpCategories.PerDiem(), CreateExpenseLocation.USAOther(), 0D, Enum::"Expense Justification"::" ", false, '', '', ''); + end; +} diff --git a/src/Apps/W1/ExpenseAgent/demo data/Country/ES/ESExpSubCategories.Codeunit.al b/src/Apps/W1/ExpenseAgent/demo data/Country/ES/ESExpSubCategories.Codeunit.al new file mode 100644 index 00000000000..f474a3fba63 --- /dev/null +++ b/src/Apps/W1/ExpenseAgent/demo data/Country/ES/ESExpSubCategories.Codeunit.al @@ -0,0 +1,39 @@ +// ------------------------------------------------------------------------------------------------ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. See License.txt in the project root for license information. +// ------------------------------------------------------------------------------------------------ +namespace Microsoft.ExpenseAgent; + +codeunit 8281 "ES Exp. SubCategories" +{ + InherentEntitlements = X; + InherentPermissions = X; + + trigger OnRun() + var + ContosoExpenseAgent: Codeunit "Contoso Expense Agent"; + ESExpCategories: Codeunit "ES Exp. Categories"; + begin + // PER-DIEM subcategories + ContosoExpenseAgent.InsertExpenseSubcategory(Country(), ESExpCategories.PerDiem(), LocalCountryPerDiemLbl, LocalCountryPerDiemPostingLbl, false, true, false); + ContosoExpenseAgent.InsertExpenseSubcategory(Intl(), ESExpCategories.PerDiem(), InternationalPerDiemLbl, InternationalPerDiemPostingLbl, false, true, false); + end; + + var + CountryTok: Label 'COUNTRY', MaxLength = 20, Locked = true; + IntlTok: Label 'INTL', MaxLength = 20, Locked = true; + LocalCountryPerDiemLbl: Label 'Daily per-diem allowance based on domestic travel rates, paid instead of individual meal or incidental expense reimbursements.', MaxLength = 250; + InternationalPerDiemLbl: Label 'Daily per-diem allowance for international business travel, based on applicable foreign travel rates.', MaxLength = 250; + LocalCountryPerDiemPostingLbl: Label 'Local country per-diem', MaxLength = 100; + InternationalPerDiemPostingLbl: Label 'International per-diem', MaxLength = 100; + + procedure Country(): Code[20] + begin + exit(CountryTok); + end; + + procedure Intl(): Code[20] + begin + exit(IntlTok); + end; +} diff --git a/src/Apps/W1/ExpenseAgent/demo data/Country/ES/ESExpense.Codeunit.al b/src/Apps/W1/ExpenseAgent/demo data/Country/ES/ESExpense.Codeunit.al new file mode 100644 index 00000000000..e6c4d5c4af4 --- /dev/null +++ b/src/Apps/W1/ExpenseAgent/demo data/Country/ES/ESExpense.Codeunit.al @@ -0,0 +1,51 @@ +// ------------------------------------------------------------------------------------------------ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. See License.txt in the project root for license information. +// ------------------------------------------------------------------------------------------------ +namespace Microsoft.ExpenseAgent; + +using Microsoft.DemoTool.Helpers; + +codeunit 8284 "ES Expense" +{ + InherentEntitlements = X; + InherentPermissions = X; + Permissions = tabledata "Expense Per Diem" = rim; + + trigger OnRun() + begin + CreateOpenExpense(); + end; + + local procedure CreateOpenExpense() + var + Expense: Record Expense; + ContosoExpenseAgent: Codeunit "Contoso Expense Agent"; + CreateExpenseLocation: Codeunit "Create Expense Location"; + begin + Expense := ContosoExpenseAgent.InsertExpense(CreateExpenseUser.EH(), ESExpCategories.PerDiem(), CreateExpenseLocation.DenmarkAll(), PerDiemByAssignedPolicyLbl, '', ContosoUtility.AdjustDate(19030203D), '', 0, '', CreateExpensePaymentMethod.Cash(), true, false, '', CreateDateTime(ContosoUtility.AdjustDate(19030115D), 144000T), CreateDateTime(ContosoUtility.AdjustDate(19030121D), 000500T), 0, 0, '', '', '', '', ''); + UpdateExpensePerDiem(Expense."No.", 10000, false, false, true); + UpdateExpensePerDiem(Expense."No.", 30000, false, true, false); + UpdateExpensePerDiem(Expense."No.", 40000, false, false, true); + UpdateExpensePerDiem(Expense."No.", 60000, false, true, true); + end; + + var + ContosoUtility: Codeunit "Contoso Utilities"; + CreateExpenseUser: Codeunit "Create Expense User"; + ESExpCategories: Codeunit "ES Exp. Categories"; + CreateExpensePaymentMethod: Codeunit "Create Expense Payment Method"; + PerDiemByAssignedPolicyLbl: Label 'Per-diem by assigned policy', MaxLength = 100; + + local procedure UpdateExpensePerDiem(ExpenseNo: Code[20]; LineNo: Integer; Breakfast: Boolean; Lunch: Boolean; Dinner: Boolean) + var + ExpensePerDiem: Record "Expense Per Diem"; + begin + ExpensePerDiem.Get(ExpenseNo, LineNo); + + ExpensePerDiem.Validate(Breakfast, Breakfast); + ExpensePerDiem.Validate(Lunch, Lunch); + ExpensePerDiem.Validate(Dinner, Dinner); + ExpensePerDiem.Modify(); + end; +} diff --git a/src/Apps/W1/ExpenseAgent/demo data/Country/ES/ESGLAccountNames.Codeunit.al b/src/Apps/W1/ExpenseAgent/demo data/Country/ES/ESGLAccountNames.Codeunit.al new file mode 100644 index 00000000000..f8bfa91f839 --- /dev/null +++ b/src/Apps/W1/ExpenseAgent/demo data/Country/ES/ESGLAccountNames.Codeunit.al @@ -0,0 +1,44 @@ +// ------------------------------------------------------------------------------------------------ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. See License.txt in the project root for license information. +// ------------------------------------------------------------------------------------------------ +namespace Microsoft.ExpenseAgent; + +codeunit 8276 "ES GL Account Names" +{ + Access = Internal; + InherentEntitlements = X; + InherentPermissions = X; + + var + OtherBusinessExpensesTok: Label 'Other Business Expenses', MaxLength = 100; + RemunerationAdvancesTok: Label 'Remuneration Advances', MaxLength = 100; + BanksEuroTok: Label 'Banks Euro', MaxLength = 100; + InternalResourcesTok: Label 'Internal Resources', MaxLength = 100; + ProfitOrLossTok: Label 'Profit or Loss', MaxLength = 100; + + procedure OtherBusinessExpensesName(): Text[100] + begin + exit(OtherBusinessExpensesTok); + end; + + procedure RemunerationAdvancesName(): Text[100] + begin + exit(RemunerationAdvancesTok); + end; + + procedure BanksEuroName(): Text[100] + begin + exit(BanksEuroTok); + end; + + procedure InternalResourcesName(): Text[100] + begin + exit(InternalResourcesTok); + end; + + procedure ProfitOrLossName(): Text[100] + begin + exit(ProfitOrLossTok); + end; +} diff --git a/src/Apps/W1/ExpenseAgent/demo data/Country/ES/ESPostedExpReport.Codeunit.al b/src/Apps/W1/ExpenseAgent/demo data/Country/ES/ESPostedExpReport.Codeunit.al new file mode 100644 index 00000000000..b6452ca00d9 --- /dev/null +++ b/src/Apps/W1/ExpenseAgent/demo data/Country/ES/ESPostedExpReport.Codeunit.al @@ -0,0 +1,168 @@ +// ------------------------------------------------------------------------------------------------ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. See License.txt in the project root for license information. +// ------------------------------------------------------------------------------------------------ +namespace Microsoft.ExpenseAgent; + +using Microsoft.DemoData.Finance; +using Microsoft.DemoData.HumanResources; +using Microsoft.DemoTool.Helpers; + +codeunit 8285 "ES Posted Exp. Report" +{ + SingleInstance = true; + EventSubscriberInstance = Manual; + InherentEntitlements = X; + InherentPermissions = X; + Permissions = + tabledata "Expense Per Diem" = rim, + tabledata "Expense Report Line" = rim; + + trigger OnRun() + var + ExpenseReportHeader: Record "Expense Report Header"; + begin + if ExpenseReportHeader.FindLast() then + FromExpenseReportNo := ExpenseReportHeader."No."; + + CreateExpenseReportToPost(); + + PostExpenseReport(); + end; + + [EventSubscriber(ObjectType::Codeunit, Codeunit::"Create Posted Expense Report", OnDefineExpenseAccountNo, '', false, false)] + local procedure OnDefineExpenseAccountNo(var AccountNo: Code[20]) + var + ExpenseGLAccount: Codeunit "Create Expense G/L Account"; + ESGLAccountNames: Codeunit "ES GL Account Names"; + begin + AccountNo := ExpenseGLAccount.FindGLAccountByName(ESGLAccountNames.InternalResourcesName()); + end; + + local procedure CreateExpenseReportToPost() + var + Expense: Record Expense; + ExpenseReportHeader: Record "Expense Report Header"; + CreateEmployee: Codeunit "Create Employee"; + CreateCurrency: Codeunit "Create Currency"; + ContosoUtility: Codeunit "Contoso Utilities"; + CreateExpenseUser: Codeunit "Create Expense User"; + CreateExpenseLocation: Codeunit "Create Expense Location"; + ContosoExpenseAgent: Codeunit "Contoso Expense Agent"; + CreateExpCategories: Codeunit "Create Expense Categories DM"; + ESExpCategories: Codeunit "ES Exp. Categories"; + CreateExpenseSubcategories: Codeunit "Create Expense Subcategories"; + CreateExpensePaymentMethod: Codeunit "Create Expense Payment Method"; + begin + ExpenseReportHeader := ContosoExpenseAgent.InsertExpenseReportHeader(CreateExpenseUser.JO(), ContosoUtility.AdjustDate(19021104D), ContosoUtility.AdjustDate(19021104D)); + Expense := ContosoExpenseAgent.InsertExpense(CreateExpenseUser.JO(), ESExpCategories.PerDiem(), CreateExpenseLocation.GermanyAll(), BusinessTripToHamburgLbl, '', ContosoUtility.AdjustDate(19021103D), '', 0, '', CreateExpensePaymentMethod.Cash(), true, false, '', CreateDateTime(ContosoUtility.AdjustDate(19021024D), 064500T), CreateDateTime(ContosoUtility.AdjustDate(19021027D), 161500T), 0, 0, '', '', '', '', ''); + ReleaseAndAddExpenseToExpenseReport(Expense, ExpenseReportHeader); + Expense := ContosoExpenseAgent.InsertExpense(CreateExpenseUser.JO(), CreateExpCategories.Airline(), '', AirlineTicketsLbl, '', ContosoUtility.AdjustDate(19021010D), '', 2042, MargieTravelLbl, CreateExpensePaymentMethod.Card(), true, false, '', 0DT, 0DT, 0, 0, '', '', 'TY6HJO', '', ''); + ReleaseAndAddExpenseToExpenseReport(Expense, ExpenseReportHeader); + + ExpenseReportHeader := ContosoExpenseAgent.InsertExpenseReportHeader(CreateExpenseUser.EH(), ContosoUtility.AdjustDate(19021204D), ContosoUtility.AdjustDate(19021204D)); + Expense := ContosoExpenseAgent.InsertExpense(CreateExpenseUser.EH(), CreateExpCategories.Airline(), '', AirlineTicketsDublinLbl, TravelToConferenceLbl, ContosoUtility.AdjustDate(19021106D), '', 3120, MargieTravelLbl, CreateExpensePaymentMethod.Card(), true, false, '', 0DT, 0DT, 0, 0, '', '', 'FIUXHJT', '', ''); + ReleaseAndAddExpenseToExpenseReport(Expense, ExpenseReportHeader); + Expense := ContosoExpenseAgent.InsertExpense(CreateExpenseUser.EH(), CreateExpCategories.Events(), '', ITConferenceLbl, '', ContosoUtility.AdjustDate(19021107D), CreateCurrency.EUR(), 1990, ProsewareIncLbl, CreateExpensePaymentMethod.Card(), true, false, '', 0DT, 0DT, 0, 0, '', '', 'G574576HJ656', '', ''); + ReleaseAndAddExpenseToExpenseReport(Expense, ExpenseReportHeader); + Expense := ContosoExpenseAgent.InsertExpense(CreateExpenseUser.EH(), CreateExpCategories.GroundTransportation(), '', TaxiLbl, '', ContosoUtility.AdjustDate(19021114D), CreateCurrency.EUR(), 45, TailwindTradersLbl, CreateExpensePaymentMethod.Cash(), true, false, '', 0DT, 0DT, 0, 0, '', '', '456845856867', '', ''); + ReleaseAndAddExpenseToExpenseReport(Expense, ExpenseReportHeader); + Expense := ContosoExpenseAgent.InsertExpense(CreateExpenseUser.EH(), CreateExpCategories.Entertain(), '', BusinessDinnerLbl, BusinessDinnerWithBigPotentialCustomersLbl, ContosoUtility.AdjustDate(19021116D), CreateCurrency.EUR(), 842, FourthCoffeeLbl, CreateExpensePaymentMethod.Card(), true, false, '', 0DT, 0DT, 0, 0, '', '', 'RT6457560034', '', ''); + ContosoExpenseAgent.InsertExpenseParticipant(Expense."No.", 10000, CreateExpCategories.Entertain(), Enum::"Expense Participant Type"::Employee, CreateEmployee.ManagingDirector(), '', '', '', '', ''); + ContosoExpenseAgent.InsertExpenseParticipant(Expense."No.", 20000, CreateExpCategories.Entertain(), Enum::"Expense Participant Type"::Employee, CreateEmployee.SalesManager(), '', '', '', '', ''); + ContosoExpenseAgent.InsertExpenseParticipant(Expense."No.", 30000, CreateExpCategories.Entertain(), Enum::"Expense Participant Type"::External, '', JesseHomerLbl, RelecloudLbl, '', CEOLbl, 'jesse.homer@contoso.com'); + ContosoExpenseAgent.InsertExpenseParticipant(Expense."No.", 40000, CreateExpCategories.Entertain(), Enum::"Expense Participant Type"::External, '', RobertTownesLbl, AdatumCorporationLbl, '', CEOLbl, 'robert.townes@contoso.com'); + ReleaseAndAddExpenseToExpenseReport(Expense, ExpenseReportHeader); + Expense := ContosoExpenseAgent.InsertExpense(CreateExpenseUser.EH(), CreateExpCategories.Hotels(), '', HotelStayLbl, '', ContosoUtility.AdjustDate(19021118D), CreateCurrency.EUR(), 2150, ContosoSuitesLbl, CreateExpensePaymentMethod.Card(), true, false, '', 0DT, 0DT, 0, 0, '', '', '64675S879CT987990004', '', ''); + ContosoExpenseAgent.InsertExpenseItemization(Expense."No.", 10000, CreateExpCategories.Hotels(), CreateExpenseSubcategories.Room(), AccommodationLbl, ContosoUtility.AdjustDate(19021114D), 390); + ContosoExpenseAgent.InsertExpenseItemization(Expense."No.", 20000, CreateExpCategories.Hotels(), CreateExpenseSubcategories.Breakfast(), BreakfastLbl, ContosoUtility.AdjustDate(19021115D), 35); + ContosoExpenseAgent.InsertExpenseItemization(Expense."No.", 30000, CreateExpCategories.Hotels(), CreateExpenseSubcategories.Room(), AccommodationLbl, ContosoUtility.AdjustDate(19021115D), 390); + ContosoExpenseAgent.InsertExpenseItemization(Expense."No.", 40000, CreateExpCategories.Hotels(), CreateExpenseSubcategories.Breakfast(), BreakfastLbl, ContosoUtility.AdjustDate(19021116D), 35); + ContosoExpenseAgent.InsertExpenseItemization(Expense."No.", 50000, CreateExpCategories.Hotels(), CreateExpenseSubcategories.Room(), AccommodationLbl, ContosoUtility.AdjustDate(19021116D), 390); + ContosoExpenseAgent.InsertExpenseItemization(Expense."No.", 60000, CreateExpCategories.Hotels(), CreateExpenseSubcategories.RoomService(), RoomServiceLbl, ContosoUtility.AdjustDate(19021116D), 145); + ContosoExpenseAgent.InsertExpenseItemization(Expense."No.", 70000, CreateExpCategories.Hotels(), CreateExpenseSubcategories.Breakfast(), BreakfastLbl, ContosoUtility.AdjustDate(19021117D), 35); + ContosoExpenseAgent.InsertExpenseItemization(Expense."No.", 80000, CreateExpCategories.Hotels(), CreateExpenseSubcategories.Room(), AccommodationLbl, ContosoUtility.AdjustDate(19021117D), 390); + ContosoExpenseAgent.InsertExpenseItemization(Expense."No.", 90000, CreateExpCategories.Hotels(), CreateExpenseSubcategories.Breakfast(), BreakfastLbl, ContosoUtility.AdjustDate(19021118D), 35); + ContosoExpenseAgent.InsertExpenseItemization(Expense."No.", 100000, CreateExpCategories.Hotels(), CreateExpenseSubcategories.Tax(), HotelTaxesLbl, ContosoUtility.AdjustDate(19021118D), 305); + ReleaseAndAddExpenseToExpenseReport(Expense, ExpenseReportHeader); + Expense := ContosoExpenseAgent.InsertExpense(CreateExpenseUser.EH(), CreateExpCategories.RentalCars(), '', CarRentalsLbl, '', ContosoUtility.AdjustDate(19021118D), CreateCurrency.EUR(), 622.45, VanArsdelLtdLbl, CreateExpensePaymentMethod.Card(), true, false, '', 0DT, 0DT, 0, 0, '', '', 'H6584769867J9J95789', '', ''); + ReleaseAndAddExpenseToExpenseReport(Expense, ExpenseReportHeader); + Expense := ContosoExpenseAgent.InsertExpense(CreateExpenseUser.EH(), CreateExpCategories.GroundTransportation(), '', TaxiLbl, '', ContosoUtility.AdjustDate(19021118D), CreateCurrency.EUR(), 71, TailwindTradersLbl, CreateExpensePaymentMethod.Cash(), true, false, '', 0DT, 0DT, 0, 0, '', '', '7456875687568', '', ''); + ReleaseAndAddExpenseToExpenseReport(Expense, ExpenseReportHeader); + Expense := ContosoExpenseAgent.InsertExpense(CreateExpenseUser.EH(), ESExpCategories.PerDiem(), CreateExpenseLocation.UKOther(), TripToUKLbl, '', ContosoUtility.AdjustDate(19021121D), '', 0, '', CreateExpensePaymentMethod.Cash(), true, false, '', CreateDateTime(ContosoUtility.AdjustDate(19021114D), 053000T), CreateDateTime(ContosoUtility.AdjustDate(19021118D), 220500T), 0, 0, '', '', '', '', ''); + UpdateExpensePerDiem(Expense."No.", 20000, false, false, true); + UpdateExpensePerDiem(Expense."No.", 40000, false, true, false); + ReleaseAndAddExpenseToExpenseReport(Expense, ExpenseReportHeader); + Expense := ContosoExpenseAgent.InsertExpense(CreateExpenseUser.EH(), ESExpCategories.PerDiem(), CreateExpenseLocation.Domestic(), TripToDoverLbl, '', ContosoUtility.AdjustDate(19021204D), '', 0, '', CreateExpensePaymentMethod.Cash(), true, false, '', CreateDateTime(ContosoUtility.AdjustDate(19021127D), 070000T), CreateDateTime(ContosoUtility.AdjustDate(19021129D), 145500T), 0, 0, '', '', '', '', ''); + ReleaseAndAddExpenseToExpenseReport(Expense, ExpenseReportHeader); + Expense := ContosoExpenseAgent.InsertExpense(CreateExpenseUser.EH(), CreateExpCategories.Mileage(), '', MileageLbl, '', ContosoUtility.AdjustDate(19031101D), '', 0, VanArsdelLtdLbl, CreateExpensePaymentMethod.Cash(), true, false, '', 0DT, 0DT, 0, 249, 'New York', 'Dover', 'H6584769867J9J95789', '', ''); + ReleaseAndAddExpenseToExpenseReport(Expense, ExpenseReportHeader); + end; + + var + FromExpenseReportNo: Code[20]; + BusinessTripToHamburgLbl: Label 'Business trip to Hamburg, DE', MaxLength = 100; + AirlineTicketsLbl: Label 'Airline tickets NY/FRANKFURT/HAMBURG/FRANKFURT/NY', MaxLength = 100; + MargieTravelLbl: Label 'Margie''s Travel', MaxLength = 100; + AirlineTicketsDublinLbl: Label 'Airline tickets NY/DUBLIN/NY', MaxLength = 100; + TravelToConferenceLbl: Label 'Travel to the conference', MaxLength = 100; + ITConferenceLbl: Label 'IT Conference', MaxLength = 100; + ProsewareIncLbl: Label 'Proseware, Inc.', MaxLength = 100; + TaxiLbl: Label 'Taxi', MaxLength = 100; + TailwindTradersLbl: Label 'Tailwind Traders', MaxLength = 100; + BusinessDinnerLbl: Label 'Business Dinner', MaxLength = 100; + BusinessDinnerWithBigPotentialCustomersLbl: Label 'Business dinner with a big potential customers', MaxLength = 100; + FourthCoffeeLbl: Label 'Fourth Coffee', MaxLength = 100; + JesseHomerLbl: Label 'Jesse Homer', MaxLength = 100; + RelecloudLbl: Label 'Relecloud', MaxLength = 100; + RobertTownesLbl: Label 'Robert Townes', MaxLength = 100; + AdatumCorporationLbl: Label 'Adatum Corporation', MaxLength = 100; + HotelStayLbl: Label 'Hotel stay', MaxLength = 100; + ContosoSuitesLbl: Label 'Contoso Suites', MaxLength = 100; + AccommodationLbl: Label 'Accommodation', MaxLength = 100; + BreakfastLbl: Label 'Breakfast', MaxLength = 100; + HotelTaxesLbl: Label 'Hotel Taxes', MaxLength = 100; + RoomServiceLbl: Label 'Room service', MaxLength = 100; + CarRentalsLbl: Label 'Car Rentals', MaxLength = 100; + VanArsdelLtdLbl: Label 'VanArsdel, Ltd.', MaxLength = 100; + TripToUKLbl: Label 'Trip to UK', MaxLength = 100; + TripToDoverLbl: Label 'Trip to Dover', MaxLength = 100; + MileageLbl: Label 'Mileage', MaxLength = 100; + CEOLbl: Label 'CEO', MaxLength = 30; + + local procedure ReleaseAndAddExpenseToExpenseReport(Expense: Record Expense; ExpenseReportHeader: Record "Expense Report Header") + var + ReleaseExpenseDocument: Codeunit "Release Expense Document"; + CreateExpenseReport: Codeunit "Create Expense Report"; + begin + Expense.Get(Expense."No."); + ReleaseExpenseDocument.Run(Expense); + + CreateExpenseReport.AddSingleExpenseToExpenseReport(Expense, ExpenseReportHeader); + end; + + local procedure PostExpenseReport() + var + ExpenseReportHeader: Record "Expense Report Header"; + begin + if FromExpenseReportNo <> '' then + ExpenseReportHeader.SetFilter("No.", '>%1', FromExpenseReportNo); + + if ExpenseReportHeader.FindSet() then + repeat + Codeunit.Run(Codeunit::"Expense Report-Post", ExpenseReportHeader); + until ExpenseReportHeader.Next() = 0; + end; + + local procedure UpdateExpensePerDiem(ExpenseNo: Code[20]; LineNo: Integer; Breakfast: Boolean; Lunch: Boolean; Dinner: Boolean) + var + ExpensePerDiem: Record "Expense Per Diem"; + begin + ExpensePerDiem.Get(ExpenseNo, LineNo); + + ExpensePerDiem.Validate(Breakfast, Breakfast); + ExpensePerDiem.Validate(Lunch, Lunch); + ExpensePerDiem.Validate(Dinner, Dinner); + ExpensePerDiem.Modify(); + end; +} diff --git a/src/Apps/W1/ExpenseAgent/demo data/Country/ES/ESUpdEmpPostingGrp.Codeunit.al b/src/Apps/W1/ExpenseAgent/demo data/Country/ES/ESUpdEmpPostingGrp.Codeunit.al new file mode 100644 index 00000000000..8dddad50362 --- /dev/null +++ b/src/Apps/W1/ExpenseAgent/demo data/Country/ES/ESUpdEmpPostingGrp.Codeunit.al @@ -0,0 +1,31 @@ +// ------------------------------------------------------------------------------------------------ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. See License.txt in the project root for license information. +// ------------------------------------------------------------------------------------------------ +namespace Microsoft.ExpenseAgent; + +using Microsoft.DemoData.HumanResources; + +codeunit 8279 "ES Upd. Emp. Posting Grp" +{ + InherentEntitlements = X; + InherentPermissions = X; + + trigger OnRun() + begin + UpdateEmployeePostingGroup(); + end; + + local procedure UpdateEmployeePostingGroup() + var + ExpenseGLAccount: Codeunit "Create Expense G/L Account"; + ESExpGLAccount: Codeunit "ES Exp. GL Account"; + ESGLAccountNames: Codeunit "ES GL Account Names"; + ContosoExpenseAgent: Codeunit "Contoso Expense Agent"; + CreateEmployeePostingGroup: Codeunit "Create Employee Posting Group"; + begin + ContosoExpenseAgent.SetOverwriteData(true); + ContosoExpenseAgent.UpdateEmployeePostingGroup(CreateEmployeePostingGroup.EmployeeExpenses(), ExpenseGLAccount.FindGLAccountByName(ESGLAccountNames.RemunerationAdvancesName()), ESExpGLAccount.ExpensesPrepayments(), ExpenseGLAccount.FindGLAccountByName(ESGLAccountNames.BanksEuroName()), ESExpGLAccount.CompanyCreditCardsClearingAccount()); + ContosoExpenseAgent.SetOverwriteData(false); + end; +} diff --git a/src/Apps/W1/ExpenseAgent/demo data/Country/ES/ESUpdEmployee.Codeunit.al b/src/Apps/W1/ExpenseAgent/demo data/Country/ES/ESUpdEmployee.Codeunit.al new file mode 100644 index 00000000000..5a11120ff7c --- /dev/null +++ b/src/Apps/W1/ExpenseAgent/demo data/Country/ES/ESUpdEmployee.Codeunit.al @@ -0,0 +1,44 @@ +// ------------------------------------------------------------------------------------------------ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. See License.txt in the project root for license information. +// ------------------------------------------------------------------------------------------------ +namespace Microsoft.ExpenseAgent; + +using Microsoft.DemoData.HumanResources; +using Microsoft.HumanResources.Employee; + +codeunit 8286 "ES Upd. Employee" +{ + InherentEntitlements = X; + InherentPermissions = X; + Permissions = tabledata Employee = rm; + + trigger OnRun() + begin + UpdateEmployees(); + end; + + local procedure UpdateEmployees() + var + CreateEmployee: Codeunit "Create Employee"; + CreateEmployeePostingGroup: Codeunit "Create Employee Posting Group"; + begin + SetEmployeePostingGroup(CreateEmployee.ManagingDirector(), CreateEmployeePostingGroup.EmployeeExpenses()); + SetEmployeePostingGroup(CreateEmployee.SalesManager(), CreateEmployeePostingGroup.EmployeeExpenses()); + SetEmployeePostingGroup(CreateEmployee.Designer(), CreateEmployeePostingGroup.EmployeeExpenses()); + SetEmployeePostingGroup(CreateEmployee.ProductionAssistant(), CreateEmployeePostingGroup.EmployeeExpenses()); + SetEmployeePostingGroup(CreateEmployee.ProductionManager(), CreateEmployeePostingGroup.EmployeeExpenses()); + SetEmployeePostingGroup(CreateEmployee.Secretary(), CreateEmployeePostingGroup.EmployeeExpenses()); + SetEmployeePostingGroup(CreateEmployee.InventoryManager(), CreateEmployeePostingGroup.EmployeeExpenses()); + end; + + local procedure SetEmployeePostingGroup(EmployeeNo: Code[20]; PostingGroupCode: Code[20]) + var + Employee: Record Employee; + begin + if Employee.Get(EmployeeNo) then begin + Employee.Validate("Employee Posting Group", PostingGroupCode); + Employee.Modify(); + end; + end; +} diff --git a/src/Apps/W1/ExpenseAgent/demo data/Country/ExpAgentCountryResolver.Codeunit.al b/src/Apps/W1/ExpenseAgent/demo data/Country/ExpAgentCountryResolver.Codeunit.al new file mode 100644 index 00000000000..40ddf0d27d5 --- /dev/null +++ b/src/Apps/W1/ExpenseAgent/demo data/Country/ExpAgentCountryResolver.Codeunit.al @@ -0,0 +1,49 @@ +// ------------------------------------------------------------------------------------------------ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. See License.txt in the project root for license information. +// ------------------------------------------------------------------------------------------------ +namespace Microsoft.ExpenseAgent; + +using Microsoft.Foundation.Company; + +codeunit 8221 "Exp. Agent Country Resolver" +{ + Access = Internal; + InherentEntitlements = X; + InherentPermissions = X; + + procedure Resolve() CountryData: Interface "Expense Agent Country Data" + begin + CountryData := ResolveCountry(); + end; + + procedure ResolveCountry() Country: Enum "Expense Agent Country" + var + CompanyInformation: Record "Company Information"; + begin + if CompanyInformation.Get() then + case CompanyInformation."Country/Region Code" of + 'US': + exit(Country::US); + 'GB': + exit(Country::GB); + 'CA': + exit(Country::CA); + 'NZ': + exit(Country::NZ); + 'AU': + exit(Country::AU); + 'ES': + exit(Country::ES); + 'DK': + exit(Country::DK); + 'FR': + exit(Country::FR); + 'DE': + exit(Country::DE); + 'AT': + exit(Country::AT); + end; + exit(Country::Default); + end; +} diff --git a/src/Apps/W1/ExpenseAgent/demo data/Country/ExpenseAgentCountry.Enum.al b/src/Apps/W1/ExpenseAgent/demo data/Country/ExpenseAgentCountry.Enum.al new file mode 100644 index 00000000000..690968c387e --- /dev/null +++ b/src/Apps/W1/ExpenseAgent/demo data/Country/ExpenseAgentCountry.Enum.al @@ -0,0 +1,66 @@ +// ------------------------------------------------------------------------------------------------ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. See License.txt in the project root for license information. +// ------------------------------------------------------------------------------------------------ +namespace Microsoft.ExpenseAgent; + +enum 8221 "Expense Agent Country" implements "Expense Agent Country Data" +{ + Extensible = false; + + value(0; Default) + { + Caption = 'Default'; + Implementation = "Expense Agent Country Data" = "W1 Country Data"; + } + value(1; US) + { + Caption = 'US'; + Implementation = "Expense Agent Country Data" = "US Country Data"; + } + value(2; GB) + { + Caption = 'GB'; + Implementation = "Expense Agent Country Data" = "GB Country Data"; + } + value(3; CA) + { + Caption = 'CA'; + Implementation = "Expense Agent Country Data" = "CA Country Data"; + } + value(4; NZ) + { + Caption = 'NZ'; + Implementation = "Expense Agent Country Data" = "NZ Country Data"; + } + value(5; AU) + { + Caption = 'AU'; + Implementation = "Expense Agent Country Data" = "AU Country Data"; + } + value(6; ES) + { + Caption = 'ES'; + Implementation = "Expense Agent Country Data" = "ES Country Data"; + } + value(7; DK) + { + Caption = 'DK'; + Implementation = "Expense Agent Country Data" = "DK Country Data"; + } + value(8; FR) + { + Caption = 'FR'; + Implementation = "Expense Agent Country Data" = "FR Country Data"; + } + value(9; DE) + { + Caption = 'DE'; + Implementation = "Expense Agent Country Data" = "DE Country Data"; + } + value(10; AT) + { + Caption = 'AT'; + Implementation = "Expense Agent Country Data" = "AT Country Data"; + } +} diff --git a/src/Apps/W1/ExpenseAgent/demo data/Country/ExpenseAgentCountryData.Interface.al b/src/Apps/W1/ExpenseAgent/demo data/Country/ExpenseAgentCountryData.Interface.al new file mode 100644 index 00000000000..9741b31ffb8 --- /dev/null +++ b/src/Apps/W1/ExpenseAgent/demo data/Country/ExpenseAgentCountryData.Interface.al @@ -0,0 +1,13 @@ +// ------------------------------------------------------------------------------------------------ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. See License.txt in the project root for license information. +// ------------------------------------------------------------------------------------------------ +namespace Microsoft.ExpenseAgent; + +interface "Expense Agent Country Data" +{ + procedure CreateSetupData(); + procedure CreateMasterData(); + procedure CreateTransactionalData(); + procedure CreateHistoricalData(); +} diff --git a/src/Apps/W1/ExpenseAgent/demo data/Country/FR/FRCountryData.Codeunit.al b/src/Apps/W1/ExpenseAgent/demo data/Country/FR/FRCountryData.Codeunit.al new file mode 100644 index 00000000000..5e516821672 --- /dev/null +++ b/src/Apps/W1/ExpenseAgent/demo data/Country/FR/FRCountryData.Codeunit.al @@ -0,0 +1,64 @@ +// ------------------------------------------------------------------------------------------------ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. See License.txt in the project root for license information. +// ------------------------------------------------------------------------------------------------ +namespace Microsoft.ExpenseAgent; + +codeunit 8300 "FR Country Data" implements "Expense Agent Country Data" +{ + Access = Internal; + InherentEntitlements = X; + InherentPermissions = X; + + procedure CreateSetupData() + var + W1CountryData: Codeunit "W1 Country Data"; + FRExpGLAccount: Codeunit "FR Exp. GL Account"; + FRExpPostingGrp: Codeunit "FR Exp. Posting Grp"; + begin + BindSubscription(FRExpGLAccount); + BindSubscription(FRExpPostingGrp); + + W1CountryData.CreateSetupData(); + Codeunit.Run(Codeunit::"FR Upd. Emp. Posting Grp"); + Codeunit.Run(Codeunit::"FR Exp. Posting Grp"); + + UnbindSubscription(FRExpPostingGrp); + UnbindSubscription(FRExpGLAccount); + end; + + procedure CreateMasterData() + var + W1CountryData: Codeunit "W1 Country Data"; + begin + W1CountryData.CreateMasterData(); + Codeunit.Run(Codeunit::"FR Exp. Categories"); + Codeunit.Run(Codeunit::"FR Exp. SubCategories"); + Codeunit.Run(Codeunit::"FR Exp. Rule Header"); + Codeunit.Run(Codeunit::"FR Exp. Rule Condition"); + end; + + procedure CreateTransactionalData() + var + W1CountryData: Codeunit "W1 Country Data"; + begin + W1CountryData.CreateTransactionalData(); + Codeunit.Run(Codeunit::"FR Expense"); + end; + + procedure CreateHistoricalData() + var + W1CountryData: Codeunit "W1 Country Data"; + FRCurrencySwapSub: Codeunit "FR Currency Swap Sub"; + FRPostedExpReport: Codeunit "FR Posted Exp. Report"; + begin + BindSubscription(FRCurrencySwapSub); + BindSubscription(FRPostedExpReport); + + W1CountryData.CreateHistoricalData(); + Codeunit.Run(Codeunit::"FR Posted Exp. Report"); + + UnbindSubscription(FRPostedExpReport); + UnbindSubscription(FRCurrencySwapSub); + end; +} diff --git a/src/Apps/W1/ExpenseAgent/demo data/Country/FR/FRCurrencySwapSub.Codeunit.al b/src/Apps/W1/ExpenseAgent/demo data/Country/FR/FRCurrencySwapSub.Codeunit.al new file mode 100644 index 00000000000..0b3b6c2b739 --- /dev/null +++ b/src/Apps/W1/ExpenseAgent/demo data/Country/FR/FRCurrencySwapSub.Codeunit.al @@ -0,0 +1,24 @@ +// ------------------------------------------------------------------------------------------------ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. See License.txt in the project root for license information. +// ------------------------------------------------------------------------------------------------ +namespace Microsoft.ExpenseAgent; + +using Microsoft.DemoData.Finance; + +codeunit 8310 "FR Currency Swap Sub" +{ + SingleInstance = true; + EventSubscriberInstance = Manual; + InherentEntitlements = X; + InherentPermissions = X; + + [EventSubscriber(ObjectType::Codeunit, Codeunit::"Contoso Expense Agent", OnBeforeValidateCurrencyCodeInExpense, '', false, false)] + local procedure OnBeforeValidateCurrencyCodeInExpense(var CurrencyCode: Code[10]) + var + CreateCurrency: Codeunit "Create Currency"; + begin + if CurrencyCode = CreateCurrency.EUR() then + CurrencyCode := CreateCurrency.USD(); + end; +} diff --git a/src/Apps/W1/ExpenseAgent/demo data/Country/FR/FRExpCategories.Codeunit.al b/src/Apps/W1/ExpenseAgent/demo data/Country/FR/FRExpCategories.Codeunit.al new file mode 100644 index 00000000000..139298315d8 --- /dev/null +++ b/src/Apps/W1/ExpenseAgent/demo data/Country/FR/FRExpCategories.Codeunit.al @@ -0,0 +1,31 @@ +// ------------------------------------------------------------------------------------------------ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. See License.txt in the project root for license information. +// ------------------------------------------------------------------------------------------------ +namespace Microsoft.ExpenseAgent; + +codeunit 8304 "FR Exp. Categories" +{ + InherentEntitlements = X; + InherentPermissions = X; + + trigger OnRun() + var + CreateExpenseGroup: Codeunit "Create Expense Group"; + CreateExpensePaymentMethod: Codeunit "Create Expense Payment Method"; + ContosoExpenseAgent: Codeunit "Contoso Expense Agent"; + FRExpPostingGrp: Codeunit "FR Exp. Posting Grp"; + begin + ContosoExpenseAgent.InsertExpenseCategory(PerDiem(), PerDiemByAssignedPolicyLbl, PerDiemByAssignedPolicyPostingLbl, FRExpPostingGrp.ExpensePerDiem(), Enum::"Expense Attachment Enforcement"::" ", CreateExpensePaymentMethod.Cash(), false, false, CreateExpenseGroup.Travel(), true, Enum::"Expense Reimbursement Type"::"Employee Paid", Enum::"Expense Detail Needed"::"Per Diem"); + end; + + var + PerDiemTok: Label 'PER-DIEM', MaxLength = 20, Locked = true; + PerDiemByAssignedPolicyLbl: Label 'Expenses for per-diem or daily allowance paid for business trips, typically based on travel itinerary or other proof of travel (e.g., booking or agenda), rather than individual expense receipts.', MaxLength = 250; + PerDiemByAssignedPolicyPostingLbl: Label 'Per-diem by assigned policy', MaxLength = 100; + + procedure PerDiem(): Code[20] + begin + exit(PerDiemTok); + end; +} diff --git a/src/Apps/W1/ExpenseAgent/demo data/Country/FR/FRExpGLAccount.Codeunit.al b/src/Apps/W1/ExpenseAgent/demo data/Country/FR/FRExpGLAccount.Codeunit.al new file mode 100644 index 00000000000..2687affdbd0 --- /dev/null +++ b/src/Apps/W1/ExpenseAgent/demo data/Country/FR/FRExpGLAccount.Codeunit.al @@ -0,0 +1,89 @@ +// ------------------------------------------------------------------------------------------------ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. See License.txt in the project root for license information. +// ------------------------------------------------------------------------------------------------ +namespace Microsoft.ExpenseAgent; + +using Microsoft.DemoTool.Helpers; +using Microsoft.Finance.GeneralLedger.Account; +using Microsoft.Foundation.Enums; + +codeunit 8301 "FR Exp. GL Account" +{ + SingleInstance = true; + EventSubscriberInstance = Manual; + InherentEntitlements = X; + InherentPermissions = X; + + [EventSubscriber(ObjectType::Codeunit, Codeunit::"Create Expense G/L Account", 'OnAfterAddGLAccountsForLocalization', '', false, false)] + local procedure ModifyGLAccount() + var + GLAccountCategory: Record "G/L Account Category"; + SubCategory: Text[80]; + begin + AddGLAccounts(); + + SubCategory := Format(GLAccountCategory."Account Category"::Assets, 80); + ContosoGLAccount.InsertGLAccount(CompanyCreditCards(), CompanyCreditCardsName(), "G/L Account Income/Balance"::"Balance Sheet", Enum::"G/L Account Category"::Assets, SubCategory, Enum::"G/L Account Type"::Posting, '', '', '', 0, '', Enum::"General Posting Type"::" ", '', '', true, false, false); + ContosoGLAccount.InsertGLAccount(ExpensePrepaymentAccount(), ExpensePrepaymentAccountName(), "G/L Account Income/Balance"::"Balance Sheet", Enum::"G/L Account Category"::Assets, SubCategory, Enum::"G/L Account Type"::Posting, '', '', '', 0, '', Enum::"General Posting Type"::" ", '', '', true, false, false); + + SubCategory := Format(GLAccountCategory."Account Category"::Expense, 80); + ContosoGLAccount.InsertGLAccount(ExpenseGLAccount.PerDiemTravelExpensesAccount(), ExpenseGLAccount.PerDiemTravelExpensesAccountName(), "G/L Account Income/Balance"::"Income Statement", Enum::"G/L Account Category"::Expense, SubCategory, Enum::"G/L Account Type"::Posting, '', '', '', 0, '', Enum::"General Posting Type"::Purchase, '', '', true, false, false); + ContosoGLAccount.InsertGLAccount(ExpenseGLAccount.MileageTravelExpensesAccount(), ExpenseGLAccount.MileageTravelExpensesAccountName(), "G/L Account Income/Balance"::"Income Statement", Enum::"G/L Account Category"::Expense, SubCategory, Enum::"G/L Account Type"::Posting, '', '', '', 0, '', Enum::"General Posting Type"::Purchase, '', '', true, false, false); + ContosoGLAccount.InsertGLAccount(ExpenseGLAccount.MealExpensesDeductibleAccount(), ExpenseGLAccount.MealExpensesDeductibleAccountName(), "G/L Account Income/Balance"::"Income Statement", Enum::"G/L Account Category"::Expense, SubCategory, Enum::"G/L Account Type"::Posting, '', '', '', 0, '', Enum::"General Posting Type"::Purchase, '', '', true, false, false); + ContosoGLAccount.InsertGLAccount(ExpenseGLAccount.MealExpensesNondeductibleAccount(), ExpenseGLAccount.MealExpensesNondeductibleAccountName(), "G/L Account Income/Balance"::"Income Statement", Enum::"G/L Account Category"::Expense, SubCategory, Enum::"G/L Account Type"::Posting, '', '', '', 0, '', Enum::"General Posting Type"::Purchase, '', '', true, false, false); + ContosoGLAccount.InsertGLAccount(RentalCarExpenses(), RentalCarExpensesName(), "G/L Account Income/Balance"::"Income Statement", Enum::"G/L Account Category"::Expense, SubCategory, Enum::"G/L Account Type"::Posting, '', '', '', 0, '', Enum::"General Posting Type"::Purchase, '', '', true, false, false); + ContosoGLAccount.InsertGLAccount(ExpenseGLAccount.OtherTravelExpensesAccount(), ExpenseGLAccount.OtherTravelExpensesAccountName(), "G/L Account Income/Balance"::"Income Statement", Enum::"G/L Account Category"::Expense, SubCategory, Enum::"G/L Account Type"::Posting, '', '', '', 0, '', Enum::"General Posting Type"::Purchase, '', '', true, false, false); + ContosoGLAccount.InsertGLAccount(ExpenseGLAccount.OtherNondeductibleTravelExpensesAccount(), ExpenseGLAccount.OtherNondeductibleTravelExpensesAccountName(), "G/L Account Income/Balance"::"Income Statement", Enum::"G/L Account Category"::Expense, SubCategory, Enum::"G/L Account Type"::Posting, '', '', '', 0, '', Enum::"General Posting Type"::Purchase, '', '', true, false, false); + end; + + local procedure AddGLAccounts() + begin + ContosoGLAccount.AddAccountForLocalization(CompanyCreditCardsName(), '512900'); + ContosoGLAccount.AddAccountForLocalization(ExpensePrepaymentAccountName(), '486200'); + ContosoGLAccount.AddAccountForLocalization(ExpenseGLAccount.PerDiemTravelExpensesAccountName(), '625110'); + ContosoGLAccount.AddAccountForLocalization(ExpenseGLAccount.MileageTravelExpensesAccountName(), '625120'); + ContosoGLAccount.AddAccountForLocalization(ExpenseGLAccount.MealExpensesDeductibleAccountName(), '625200'); + ContosoGLAccount.AddAccountForLocalization(ExpenseGLAccount.MealExpensesNondeductibleAccountName(), '625210'); + ContosoGLAccount.AddAccountForLocalization(RentalCarExpensesName(), '625130'); + ContosoGLAccount.AddAccountForLocalization(ExpenseGLAccount.OtherTravelExpensesAccountName(), '625180'); + ContosoGLAccount.AddAccountForLocalization(ExpenseGLAccount.OtherNondeductibleTravelExpensesAccountName(), '625290'); + end; + + var + ContosoGLAccount: Codeunit "Contoso GL Account"; + ExpenseGLAccount: Codeunit "Create Expense G/L Account"; + CompanyCreditCardsTok: Label 'Company credit cards', MaxLength = 100; + ExpensePrepaymentAccountTok: Label 'Expense prepayment account', MaxLength = 100; + RentalCarExpensesTok: Label 'Rental car expenses', MaxLength = 100; + + procedure CompanyCreditCards(): Code[20] + begin + exit(ContosoGLAccount.GetAccountNo(CompanyCreditCardsName())); + end; + + procedure CompanyCreditCardsName(): Text[100] + begin + exit(CompanyCreditCardsTok); + end; + + procedure ExpensePrepaymentAccount(): Code[20] + begin + exit(ContosoGLAccount.GetAccountNo(ExpensePrepaymentAccountName())); + end; + + procedure ExpensePrepaymentAccountName(): Text[100] + begin + exit(ExpensePrepaymentAccountTok); + end; + + procedure RentalCarExpenses(): Code[20] + begin + exit(ContosoGLAccount.GetAccountNo(RentalCarExpensesName())); + end; + + procedure RentalCarExpensesName(): Text[100] + begin + exit(RentalCarExpensesTok); + end; +} diff --git a/src/Apps/W1/ExpenseAgent/demo data/Country/FR/FRExpPostingGrp.Codeunit.al b/src/Apps/W1/ExpenseAgent/demo data/Country/FR/FRExpPostingGrp.Codeunit.al new file mode 100644 index 00000000000..ab370d6780f --- /dev/null +++ b/src/Apps/W1/ExpenseAgent/demo data/Country/FR/FRExpPostingGrp.Codeunit.al @@ -0,0 +1,66 @@ +// ------------------------------------------------------------------------------------------------ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. See License.txt in the project root for license information. +// ------------------------------------------------------------------------------------------------ +namespace Microsoft.ExpenseAgent; + +using Microsoft.DemoData.Finance; + +codeunit 8302 "FR Exp. Posting Grp" +{ + SingleInstance = true; + EventSubscriberInstance = Manual; + InherentEntitlements = X; + InherentPermissions = X; + + trigger OnRun() + var + ContosoExpenseAgent: Codeunit "Contoso Expense Agent"; + begin + ContosoExpenseAgent.InsertExpensePostingGroup(ExpensePerDiem(), ExpensePerDiemLbl); + end; + + [EventSubscriber(ObjectType::Table, Database::"Expense Posting Group", 'OnBeforeInsertEvent', '', false, false)] + local procedure OnInsertRecord(var Rec: Record "Expense Posting Group") + var + CreateGLAccount: Codeunit "Create G/L Account"; + ExpenseGLAccount: Codeunit "Create Expense G/L Account"; + FRExpGLAccount: Codeunit "FR Exp. GL Account"; + CreateExpensePostingGroup: Codeunit "Create Expense Posting Group"; + begin + case Rec.Code of + CreateExpensePostingGroup.ExpenseEntertainment(): + ValidateRecordFields(Rec, ExpenseGLAccount.FindGLAccountByName(CreateGLAccount.EntertainmentandPRName()), '', FRExpGLAccount.ExpensePrepaymentAccount(), ExpenseGLAccount.FindGLAccountByName(CreateGLAccount.ApplicationRoundingName()), ExpenseGLAccount.FindGLAccountByName(CreateGLAccount.ApplicationRoundingName())); + CreateExpensePostingGroup.ExpenseMeals(): + ValidateRecordFields(Rec, ExpenseGLAccount.MealExpensesDeductibleAccount(), ExpenseGLAccount.MealExpensesNondeductibleAccount(), FRExpGLAccount.ExpensePrepaymentAccount(), ExpenseGLAccount.FindGLAccountByName(CreateGLAccount.ApplicationRoundingName()), ExpenseGLAccount.FindGLAccountByName(CreateGLAccount.ApplicationRoundingName())); + CreateExpensePostingGroup.ExpenseMileage(): + ValidateRecordFields(Rec, ExpenseGLAccount.MileageTravelExpensesAccount(), '', FRExpGLAccount.ExpensePrepaymentAccount(), ExpenseGLAccount.FindGLAccountByName(CreateGLAccount.ApplicationRoundingName()), ExpenseGLAccount.FindGLAccountByName(CreateGLAccount.ApplicationRoundingName())); + CreateExpensePostingGroup.ExpenseOther(): + ValidateRecordFields(Rec, ExpenseGLAccount.OtherTravelExpensesAccount(), ExpenseGLAccount.OtherNondeductibleTravelExpensesAccount(), FRExpGLAccount.ExpensePrepaymentAccount(), ExpenseGLAccount.FindGLAccountByName(CreateGLAccount.ApplicationRoundingName()), ExpenseGLAccount.FindGLAccountByName(CreateGLAccount.ApplicationRoundingName())); + ExpensePerDiem(): + ValidateRecordFields(Rec, ExpenseGLAccount.PerDiemTravelExpensesAccount(), '', FRExpGLAccount.ExpensePrepaymentAccount(), ExpenseGLAccount.FindGLAccountByName(CreateGLAccount.ApplicationRoundingName()), ExpenseGLAccount.FindGLAccountByName(CreateGLAccount.ApplicationRoundingName())); + CreateExpensePostingGroup.ExpenseTravel(): + ValidateRecordFields(Rec, ExpenseGLAccount.FindGLAccountByName(CreateGLAccount.TravelName()), ExpenseGLAccount.OtherNondeductibleTravelExpensesAccount(), FRExpGLAccount.ExpensePrepaymentAccount(), ExpenseGLAccount.FindGLAccountByName(CreateGLAccount.ApplicationRoundingName()), ExpenseGLAccount.FindGLAccountByName(CreateGLAccount.ApplicationRoundingName())); + CreateExpensePostingGroup.ExpenseRentalCars(): + ValidateRecordFields(Rec, FRExpGLAccount.RentalCarExpenses(), '', FRExpGLAccount.ExpensePrepaymentAccount(), ExpenseGLAccount.FindGLAccountByName(CreateGLAccount.ApplicationRoundingName()), ExpenseGLAccount.FindGLAccountByName(CreateGLAccount.ApplicationRoundingName())); + end; + end; + + local procedure ValidateRecordFields(var ExpensePostingGroup: Record "Expense Posting Group"; RefundableDebitAccount: Code[20]; NonRefundableDebitAccount: Code[20]; PrepaymentCreditAccount: Code[20]; ExpenseDebitRoundingAccount: Code[20]; ExpenseCreditRoundingAccount: Code[20]) + begin + ExpensePostingGroup.Validate("Refundable Debit Account", RefundableDebitAccount); + ExpensePostingGroup.Validate("Non-Refundable Debit Account", NonRefundableDebitAccount); + ExpensePostingGroup.Validate("Prepayment Credit Account", PrepaymentCreditAccount); + ExpensePostingGroup.Validate("Debit Rounding Account", ExpenseDebitRoundingAccount); + ExpensePostingGroup.Validate("Credit Rounding Account", ExpenseCreditRoundingAccount); + end; + + var + ExpensePERDIEMTok: Label 'EXPENSE-PERDIEM', MaxLength = 20, Locked = true; + ExpensePerDiemLbl: Label 'Expense - Per Diem', MaxLength = 100; + + procedure ExpensePerDiem(): Code[20] + begin + exit(ExpensePERDIEMTok); + end; +} diff --git a/src/Apps/W1/ExpenseAgent/demo data/Country/FR/FRExpRuleCondition.Codeunit.al b/src/Apps/W1/ExpenseAgent/demo data/Country/FR/FRExpRuleCondition.Codeunit.al new file mode 100644 index 00000000000..151833e0143 --- /dev/null +++ b/src/Apps/W1/ExpenseAgent/demo data/Country/FR/FRExpRuleCondition.Codeunit.al @@ -0,0 +1,26 @@ +// ------------------------------------------------------------------------------------------------ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. See License.txt in the project root for license information. +// ------------------------------------------------------------------------------------------------ +namespace Microsoft.ExpenseAgent; + +codeunit 8307 "FR Exp. Rule Condition" +{ + InherentEntitlements = X; + InherentPermissions = X; + + trigger OnRun() + var + FRExpCategories: Codeunit "FR Exp. Categories"; + CreateExpenseLocation: Codeunit "Create Expense Location"; + ContosoExpenseAgent: Codeunit "Contoso Expense Agent"; + begin + ContosoExpenseAgent.InsertExpenseRuleCondition(FRExpCategories.PerDiem(), CreateExpenseLocation.CanadaAll(), 0D, 10000, Enum::"Expense Rule Condition Type"::"Daily Rate", 125); + ContosoExpenseAgent.InsertExpenseRuleCondition(FRExpCategories.PerDiem(), CreateExpenseLocation.DenmarkAll(), 0D, 10000, Enum::"Expense Rule Condition Type"::"Daily Rate", 450); + ContosoExpenseAgent.InsertExpenseRuleCondition(FRExpCategories.PerDiem(), CreateExpenseLocation.Domestic(), 0D, 10000, Enum::"Expense Rule Condition Type"::"Daily Rate", 50); + ContosoExpenseAgent.InsertExpenseRuleCondition(FRExpCategories.PerDiem(), CreateExpenseLocation.FranceAll(), 0D, 10000, Enum::"Expense Rule Condition Type"::"Daily Rate", 110); + ContosoExpenseAgent.InsertExpenseRuleCondition(FRExpCategories.PerDiem(), CreateExpenseLocation.GermanyAll(), 0D, 10000, Enum::"Expense Rule Condition Type"::"Daily Rate", 105); + ContosoExpenseAgent.InsertExpenseRuleCondition(FRExpCategories.PerDiem(), CreateExpenseLocation.UKOther(), 0D, 10000, Enum::"Expense Rule Condition Type"::"Daily Rate", 115); + ContosoExpenseAgent.InsertExpenseRuleCondition(FRExpCategories.PerDiem(), CreateExpenseLocation.USAOther(), 0D, 10000, Enum::"Expense Rule Condition Type"::"Daily Rate", 120); + end; +} diff --git a/src/Apps/W1/ExpenseAgent/demo data/Country/FR/FRExpRuleHeader.Codeunit.al b/src/Apps/W1/ExpenseAgent/demo data/Country/FR/FRExpRuleHeader.Codeunit.al new file mode 100644 index 00000000000..7c3cfd823af --- /dev/null +++ b/src/Apps/W1/ExpenseAgent/demo data/Country/FR/FRExpRuleHeader.Codeunit.al @@ -0,0 +1,29 @@ +// ------------------------------------------------------------------------------------------------ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. See License.txt in the project root for license information. +// ------------------------------------------------------------------------------------------------ +namespace Microsoft.ExpenseAgent; + +using Microsoft.DemoData.Finance; + +codeunit 8306 "FR Exp. Rule Header" +{ + InherentEntitlements = X; + InherentPermissions = X; + + trigger OnRun() + var + CreateCurrency: Codeunit "Create Currency"; + FRExpCategories: Codeunit "FR Exp. Categories"; + CreateExpenseLocation: Codeunit "Create Expense Location"; + ContosoExpenseAgent: Codeunit "Contoso Expense Agent"; + begin + ContosoExpenseAgent.InsertExpenseRuleHeader(FRExpCategories.PerDiem(), CreateExpenseLocation.CanadaAll(), 0D, Enum::"Expense Justification"::" ", false, '', CreateCurrency.CAD(), ''); + ContosoExpenseAgent.InsertExpenseRuleHeader(FRExpCategories.PerDiem(), CreateExpenseLocation.DenmarkAll(), 0D, Enum::"Expense Justification"::" ", false, '', CreateCurrency.USD(), ''); + ContosoExpenseAgent.InsertExpenseRuleHeader(FRExpCategories.PerDiem(), CreateExpenseLocation.Domestic(), 0D, Enum::"Expense Justification"::" ", false, '', '', ''); + ContosoExpenseAgent.InsertExpenseRuleHeader(FRExpCategories.PerDiem(), CreateExpenseLocation.FranceAll(), 0D, Enum::"Expense Justification"::" ", false, '', CreateCurrency.USD(), ''); + ContosoExpenseAgent.InsertExpenseRuleHeader(FRExpCategories.PerDiem(), CreateExpenseLocation.GermanyAll(), 0D, Enum::"Expense Justification"::" ", false, '', CreateCurrency.USD(), ''); + ContosoExpenseAgent.InsertExpenseRuleHeader(FRExpCategories.PerDiem(), CreateExpenseLocation.UKOther(), 0D, Enum::"Expense Justification"::" ", false, '', CreateCurrency.GBP(), ''); + ContosoExpenseAgent.InsertExpenseRuleHeader(FRExpCategories.PerDiem(), CreateExpenseLocation.USAOther(), 0D, Enum::"Expense Justification"::" ", false, '', '', ''); + end; +} diff --git a/src/Apps/W1/ExpenseAgent/demo data/Country/FR/FRExpSubCategories.Codeunit.al b/src/Apps/W1/ExpenseAgent/demo data/Country/FR/FRExpSubCategories.Codeunit.al new file mode 100644 index 00000000000..898fec78585 --- /dev/null +++ b/src/Apps/W1/ExpenseAgent/demo data/Country/FR/FRExpSubCategories.Codeunit.al @@ -0,0 +1,39 @@ +// ------------------------------------------------------------------------------------------------ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. See License.txt in the project root for license information. +// ------------------------------------------------------------------------------------------------ +namespace Microsoft.ExpenseAgent; + +codeunit 8305 "FR Exp. SubCategories" +{ + InherentEntitlements = X; + InherentPermissions = X; + + trigger OnRun() + var + ContosoExpenseAgent: Codeunit "Contoso Expense Agent"; + FRExpCategories: Codeunit "FR Exp. Categories"; + begin + // PER-DIEM subcategories + ContosoExpenseAgent.InsertExpenseSubcategory(Country(), FRExpCategories.PerDiem(), LocalCountryPerDiemLbl, LocalCountryPerDiemPostingLbl, false, true, false); + ContosoExpenseAgent.InsertExpenseSubcategory(Intl(), FRExpCategories.PerDiem(), InternationalPerDiemLbl, InternationalPerDiemPostingLbl, false, true, false); + end; + + var + CountryTok: Label 'COUNTRY', MaxLength = 20, Locked = true; + IntlTok: Label 'INTL', MaxLength = 20, Locked = true; + LocalCountryPerDiemLbl: Label 'Daily per-diem allowance based on domestic travel rates, paid instead of individual meal or incidental expense reimbursements.', MaxLength = 250; + InternationalPerDiemLbl: Label 'Daily per-diem allowance for international business travel, based on applicable foreign travel rates.', MaxLength = 250; + LocalCountryPerDiemPostingLbl: Label 'Local country per-diem', MaxLength = 100; + InternationalPerDiemPostingLbl: Label 'International per-diem', MaxLength = 100; + + procedure Country(): Code[20] + begin + exit(CountryTok); + end; + + procedure Intl(): Code[20] + begin + exit(IntlTok); + end; +} diff --git a/src/Apps/W1/ExpenseAgent/demo data/Country/FR/FRExpense.Codeunit.al b/src/Apps/W1/ExpenseAgent/demo data/Country/FR/FRExpense.Codeunit.al new file mode 100644 index 00000000000..0006405f379 --- /dev/null +++ b/src/Apps/W1/ExpenseAgent/demo data/Country/FR/FRExpense.Codeunit.al @@ -0,0 +1,51 @@ +// ------------------------------------------------------------------------------------------------ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. See License.txt in the project root for license information. +// ------------------------------------------------------------------------------------------------ +namespace Microsoft.ExpenseAgent; + +using Microsoft.DemoTool.Helpers; + +codeunit 8308 "FR Expense" +{ + InherentEntitlements = X; + InherentPermissions = X; + Permissions = tabledata "Expense Per Diem" = rim; + + trigger OnRun() + begin + CreateOpenExpense(); + end; + + local procedure CreateOpenExpense() + var + Expense: Record Expense; + ContosoExpenseAgent: Codeunit "Contoso Expense Agent"; + CreateExpenseLocation: Codeunit "Create Expense Location"; + begin + Expense := ContosoExpenseAgent.InsertExpense(CreateExpenseUser.EH(), FRExpCategories.PerDiem(), CreateExpenseLocation.FranceAll(), PerDiemByAssignedPolicyLbl, '', ContosoUtility.AdjustDate(19030203D), '', 0, '', CreateExpensePaymentMethod.Cash(), true, false, '', CreateDateTime(ContosoUtility.AdjustDate(19030115D), 144000T), CreateDateTime(ContosoUtility.AdjustDate(19030121D), 000500T), 0, 0, '', '', '', '', ''); + UpdateExpensePerDiem(Expense."No.", 10000, false, false, true); + UpdateExpensePerDiem(Expense."No.", 30000, false, true, false); + UpdateExpensePerDiem(Expense."No.", 40000, false, false, true); + UpdateExpensePerDiem(Expense."No.", 60000, false, true, true); + end; + + var + ContosoUtility: Codeunit "Contoso Utilities"; + CreateExpenseUser: Codeunit "Create Expense User"; + FRExpCategories: Codeunit "FR Exp. Categories"; + CreateExpensePaymentMethod: Codeunit "Create Expense Payment Method"; + PerDiemByAssignedPolicyLbl: Label 'Per-diem by assigned policy', MaxLength = 100; + + local procedure UpdateExpensePerDiem(ExpenseNo: Code[20]; LineNo: Integer; Breakfast: Boolean; Lunch: Boolean; Dinner: Boolean) + var + ExpensePerDiem: Record "Expense Per Diem"; + begin + ExpensePerDiem.Get(ExpenseNo, LineNo); + + ExpensePerDiem.Validate(Breakfast, Breakfast); + ExpensePerDiem.Validate(Lunch, Lunch); + ExpensePerDiem.Validate(Dinner, Dinner); + ExpensePerDiem.Modify(); + end; +} diff --git a/src/Apps/W1/ExpenseAgent/demo data/Country/FR/FRPostedExpReport.Codeunit.al b/src/Apps/W1/ExpenseAgent/demo data/Country/FR/FRPostedExpReport.Codeunit.al new file mode 100644 index 00000000000..ff70818d5db --- /dev/null +++ b/src/Apps/W1/ExpenseAgent/demo data/Country/FR/FRPostedExpReport.Codeunit.al @@ -0,0 +1,168 @@ +// ------------------------------------------------------------------------------------------------ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. See License.txt in the project root for license information. +// ------------------------------------------------------------------------------------------------ +namespace Microsoft.ExpenseAgent; + +using Microsoft.DemoData.Finance; +using Microsoft.DemoData.HumanResources; +using Microsoft.DemoTool.Helpers; + +codeunit 8309 "FR Posted Exp. Report" +{ + SingleInstance = true; + EventSubscriberInstance = Manual; + InherentEntitlements = X; + InherentPermissions = X; + Permissions = + tabledata "Expense Per Diem" = rim, + tabledata "Expense Report Line" = rim; + + trigger OnRun() + var + ExpenseReportHeader: Record "Expense Report Header"; + begin + if ExpenseReportHeader.FindLast() then + FromExpenseReportNo := ExpenseReportHeader."No."; + + CreateExpenseReportToPost(); + + PostExpenseReport(); + end; + + [EventSubscriber(ObjectType::Codeunit, Codeunit::"Create Posted Expense Report", OnDefineExpenseAccountNo, '', false, false)] + local procedure OnDefineExpenseAccountNo(var AccountNo: Code[20]) + var + CreateGLAccount: Codeunit "Create G/L Account"; + ExpenseGLAccount: Codeunit "Create Expense G/L Account"; + begin + AccountNo := ExpenseGLAccount.FindGLAccountByName(CreateGLAccount.SalesResourcesExportName()); + end; + + local procedure CreateExpenseReportToPost() + var + Expense: Record Expense; + ExpenseReportHeader: Record "Expense Report Header"; + CreateEmployee: Codeunit "Create Employee"; + CreateCurrency: Codeunit "Create Currency"; + ContosoUtility: Codeunit "Contoso Utilities"; + CreateExpenseUser: Codeunit "Create Expense User"; + CreateExpenseLocation: Codeunit "Create Expense Location"; + ContosoExpenseAgent: Codeunit "Contoso Expense Agent"; + CreateExpCategories: Codeunit "Create Expense Categories DM"; + FRExpCategories: Codeunit "FR Exp. Categories"; + CreateExpenseSubcategories: Codeunit "Create Expense Subcategories"; + CreateExpensePaymentMethod: Codeunit "Create Expense Payment Method"; + begin + ExpenseReportHeader := ContosoExpenseAgent.InsertExpenseReportHeader(CreateExpenseUser.JO(), ContosoUtility.AdjustDate(19021104D), ContosoUtility.AdjustDate(19021104D)); + Expense := ContosoExpenseAgent.InsertExpense(CreateExpenseUser.JO(), FRExpCategories.PerDiem(), CreateExpenseLocation.GermanyAll(), BusinessTripToHamburgLbl, '', ContosoUtility.AdjustDate(19021103D), '', 0, '', CreateExpensePaymentMethod.Cash(), true, false, '', CreateDateTime(ContosoUtility.AdjustDate(19021024D), 064500T), CreateDateTime(ContosoUtility.AdjustDate(19021027D), 161500T), 0, 0, '', '', '', '', ''); + ReleaseAndAddExpenseToExpenseReport(Expense, ExpenseReportHeader); + Expense := ContosoExpenseAgent.InsertExpense(CreateExpenseUser.JO(), CreateExpCategories.Airline(), '', AirlineTicketsLbl, '', ContosoUtility.AdjustDate(19021010D), '', 2042, MargieTravelLbl, CreateExpensePaymentMethod.Card(), true, false, '', 0DT, 0DT, 0, 0, '', '', 'TY6HJO', '', ''); + ReleaseAndAddExpenseToExpenseReport(Expense, ExpenseReportHeader); + + ExpenseReportHeader := ContosoExpenseAgent.InsertExpenseReportHeader(CreateExpenseUser.EH(), ContosoUtility.AdjustDate(19021204D), ContosoUtility.AdjustDate(19021204D)); + Expense := ContosoExpenseAgent.InsertExpense(CreateExpenseUser.EH(), CreateExpCategories.Airline(), '', AirlineTicketsDublinLbl, TravelToConferenceLbl, ContosoUtility.AdjustDate(19021106D), '', 3120, MargieTravelLbl, CreateExpensePaymentMethod.Card(), true, false, '', 0DT, 0DT, 0, 0, '', '', 'FIUXHJT', '', ''); + ReleaseAndAddExpenseToExpenseReport(Expense, ExpenseReportHeader); + Expense := ContosoExpenseAgent.InsertExpense(CreateExpenseUser.EH(), CreateExpCategories.Events(), '', ITConferenceLbl, '', ContosoUtility.AdjustDate(19021107D), CreateCurrency.EUR(), 1990, ProsewareIncLbl, CreateExpensePaymentMethod.Card(), true, false, '', 0DT, 0DT, 0, 0, '', '', 'G574576HJ656', '', ''); + ReleaseAndAddExpenseToExpenseReport(Expense, ExpenseReportHeader); + Expense := ContosoExpenseAgent.InsertExpense(CreateExpenseUser.EH(), CreateExpCategories.GroundTransportation(), '', TaxiLbl, '', ContosoUtility.AdjustDate(19021114D), CreateCurrency.EUR(), 45, TailwindTradersLbl, CreateExpensePaymentMethod.Cash(), true, false, '', 0DT, 0DT, 0, 0, '', '', '456845856867', '', ''); + ReleaseAndAddExpenseToExpenseReport(Expense, ExpenseReportHeader); + Expense := ContosoExpenseAgent.InsertExpense(CreateExpenseUser.EH(), CreateExpCategories.Entertain(), '', BusinessDinnerLbl, BusinessDinnerWithBigPotentialCustomersLbl, ContosoUtility.AdjustDate(19021116D), CreateCurrency.EUR(), 842, FourthCoffeeLbl, CreateExpensePaymentMethod.Card(), true, false, '', 0DT, 0DT, 0, 0, '', '', 'RT6457560034', '', ''); + ContosoExpenseAgent.InsertExpenseParticipant(Expense."No.", 10000, CreateExpCategories.Entertain(), Enum::"Expense Participant Type"::Employee, CreateEmployee.ManagingDirector(), '', '', '', '', ''); + ContosoExpenseAgent.InsertExpenseParticipant(Expense."No.", 20000, CreateExpCategories.Entertain(), Enum::"Expense Participant Type"::Employee, CreateEmployee.SalesManager(), '', '', '', '', ''); + ContosoExpenseAgent.InsertExpenseParticipant(Expense."No.", 30000, CreateExpCategories.Entertain(), Enum::"Expense Participant Type"::External, '', JesseHomerLbl, RelecloudLbl, '', CEOLbl, 'jesse.homer@contoso.com'); + ContosoExpenseAgent.InsertExpenseParticipant(Expense."No.", 40000, CreateExpCategories.Entertain(), Enum::"Expense Participant Type"::External, '', RobertTownesLbl, AdatumCorporationLbl, '', CEOLbl, 'robert.townes@contoso.com'); + ReleaseAndAddExpenseToExpenseReport(Expense, ExpenseReportHeader); + Expense := ContosoExpenseAgent.InsertExpense(CreateExpenseUser.EH(), CreateExpCategories.Hotels(), '', HotelStayLbl, '', ContosoUtility.AdjustDate(19021118D), CreateCurrency.EUR(), 2150, ContosoSuitesLbl, CreateExpensePaymentMethod.Card(), true, false, '', 0DT, 0DT, 0, 0, '', '', '64675S879CT987990004', '', ''); + ContosoExpenseAgent.InsertExpenseItemization(Expense."No.", 10000, CreateExpCategories.Hotels(), CreateExpenseSubcategories.Room(), AccommodationLbl, ContosoUtility.AdjustDate(19021114D), 390); + ContosoExpenseAgent.InsertExpenseItemization(Expense."No.", 20000, CreateExpCategories.Hotels(), CreateExpenseSubcategories.Breakfast(), BreakfastLbl, ContosoUtility.AdjustDate(19021115D), 35); + ContosoExpenseAgent.InsertExpenseItemization(Expense."No.", 30000, CreateExpCategories.Hotels(), CreateExpenseSubcategories.Room(), AccommodationLbl, ContosoUtility.AdjustDate(19021115D), 390); + ContosoExpenseAgent.InsertExpenseItemization(Expense."No.", 40000, CreateExpCategories.Hotels(), CreateExpenseSubcategories.Breakfast(), BreakfastLbl, ContosoUtility.AdjustDate(19021116D), 35); + ContosoExpenseAgent.InsertExpenseItemization(Expense."No.", 50000, CreateExpCategories.Hotels(), CreateExpenseSubcategories.Room(), AccommodationLbl, ContosoUtility.AdjustDate(19021116D), 390); + ContosoExpenseAgent.InsertExpenseItemization(Expense."No.", 60000, CreateExpCategories.Hotels(), CreateExpenseSubcategories.RoomService(), RoomServiceLbl, ContosoUtility.AdjustDate(19021116D), 145); + ContosoExpenseAgent.InsertExpenseItemization(Expense."No.", 70000, CreateExpCategories.Hotels(), CreateExpenseSubcategories.Breakfast(), BreakfastLbl, ContosoUtility.AdjustDate(19021117D), 35); + ContosoExpenseAgent.InsertExpenseItemization(Expense."No.", 80000, CreateExpCategories.Hotels(), CreateExpenseSubcategories.Room(), AccommodationLbl, ContosoUtility.AdjustDate(19021117D), 390); + ContosoExpenseAgent.InsertExpenseItemization(Expense."No.", 90000, CreateExpCategories.Hotels(), CreateExpenseSubcategories.Breakfast(), BreakfastLbl, ContosoUtility.AdjustDate(19021118D), 35); + ContosoExpenseAgent.InsertExpenseItemization(Expense."No.", 100000, CreateExpCategories.Hotels(), CreateExpenseSubcategories.Tax(), HotelTaxesLbl, ContosoUtility.AdjustDate(19021118D), 305); + ReleaseAndAddExpenseToExpenseReport(Expense, ExpenseReportHeader); + Expense := ContosoExpenseAgent.InsertExpense(CreateExpenseUser.EH(), CreateExpCategories.RentalCars(), '', CarRentalsLbl, '', ContosoUtility.AdjustDate(19021118D), CreateCurrency.EUR(), 622.45, VanArsdelLtdLbl, CreateExpensePaymentMethod.Card(), true, false, '', 0DT, 0DT, 0, 0, '', '', 'H6584769867J9J95789', '', ''); + ReleaseAndAddExpenseToExpenseReport(Expense, ExpenseReportHeader); + Expense := ContosoExpenseAgent.InsertExpense(CreateExpenseUser.EH(), CreateExpCategories.GroundTransportation(), '', TaxiLbl, '', ContosoUtility.AdjustDate(19021118D), CreateCurrency.EUR(), 71, TailwindTradersLbl, CreateExpensePaymentMethod.Cash(), true, false, '', 0DT, 0DT, 0, 0, '', '', '7456875687568', '', ''); + ReleaseAndAddExpenseToExpenseReport(Expense, ExpenseReportHeader); + Expense := ContosoExpenseAgent.InsertExpense(CreateExpenseUser.EH(), FRExpCategories.PerDiem(), CreateExpenseLocation.UKOther(), TripToUKLbl, '', ContosoUtility.AdjustDate(19021121D), '', 0, '', CreateExpensePaymentMethod.Cash(), true, false, '', CreateDateTime(ContosoUtility.AdjustDate(19021114D), 053000T), CreateDateTime(ContosoUtility.AdjustDate(19021118D), 220500T), 0, 0, '', '', '', '', ''); + UpdateExpensePerDiem(Expense."No.", 20000, false, false, true); + UpdateExpensePerDiem(Expense."No.", 40000, false, true, false); + ReleaseAndAddExpenseToExpenseReport(Expense, ExpenseReportHeader); + Expense := ContosoExpenseAgent.InsertExpense(CreateExpenseUser.EH(), FRExpCategories.PerDiem(), CreateExpenseLocation.Domestic(), TripToDoverLbl, '', ContosoUtility.AdjustDate(19021204D), '', 0, '', CreateExpensePaymentMethod.Cash(), true, false, '', CreateDateTime(ContosoUtility.AdjustDate(19021127D), 070000T), CreateDateTime(ContosoUtility.AdjustDate(19021129D), 145500T), 0, 0, '', '', '', '', ''); + ReleaseAndAddExpenseToExpenseReport(Expense, ExpenseReportHeader); + Expense := ContosoExpenseAgent.InsertExpense(CreateExpenseUser.EH(), CreateExpCategories.Mileage(), '', MileageLbl, '', ContosoUtility.AdjustDate(19031101D), '', 0, VanArsdelLtdLbl, CreateExpensePaymentMethod.Cash(), true, false, '', 0DT, 0DT, 0, 249, 'New York', 'Dover', 'H6584769867J9J95789', '', ''); + ReleaseAndAddExpenseToExpenseReport(Expense, ExpenseReportHeader); + end; + + var + FromExpenseReportNo: Code[20]; + BusinessTripToHamburgLbl: Label 'Business trip to Hamburg, DE', MaxLength = 100; + AirlineTicketsLbl: Label 'Airline tickets NY/FRANKFURT/HAMBURG/FRANKFURT/NY', MaxLength = 100; + MargieTravelLbl: Label 'Margie''s Travel', MaxLength = 100; + AirlineTicketsDublinLbl: Label 'Airline tickets NY/DUBLIN/NY', MaxLength = 100; + TravelToConferenceLbl: Label 'Travel to the conference', MaxLength = 100; + ITConferenceLbl: Label 'IT Conference', MaxLength = 100; + ProsewareIncLbl: Label 'Proseware, Inc.', MaxLength = 100; + TaxiLbl: Label 'Taxi', MaxLength = 100; + TailwindTradersLbl: Label 'Tailwind Traders', MaxLength = 100; + BusinessDinnerLbl: Label 'Business Dinner', MaxLength = 100; + BusinessDinnerWithBigPotentialCustomersLbl: Label 'Business dinner with a big potential customers', MaxLength = 100; + FourthCoffeeLbl: Label 'Fourth Coffee', MaxLength = 100; + JesseHomerLbl: Label 'Jesse Homer', MaxLength = 100; + RelecloudLbl: Label 'Relecloud', MaxLength = 100; + RobertTownesLbl: Label 'Robert Townes', MaxLength = 100; + AdatumCorporationLbl: Label 'Adatum Corporation', MaxLength = 100; + HotelStayLbl: Label 'Hotel stay', MaxLength = 100; + ContosoSuitesLbl: Label 'Contoso Suites', MaxLength = 100; + AccommodationLbl: Label 'Accommodation', MaxLength = 100; + BreakfastLbl: Label 'Breakfast', MaxLength = 100; + HotelTaxesLbl: Label 'Hotel Taxes', MaxLength = 100; + RoomServiceLbl: Label 'Room service', MaxLength = 100; + CarRentalsLbl: Label 'Car Rentals', MaxLength = 100; + VanArsdelLtdLbl: Label 'VanArsdel, Ltd.', MaxLength = 100; + TripToUKLbl: Label 'Trip to UK', MaxLength = 100; + TripToDoverLbl: Label 'Trip to Dover', MaxLength = 100; + MileageLbl: Label 'Mileage', MaxLength = 100; + CEOLbl: Label 'CEO', MaxLength = 30; + + local procedure ReleaseAndAddExpenseToExpenseReport(Expense: Record Expense; ExpenseReportHeader: Record "Expense Report Header") + var + ReleaseExpenseDocument: Codeunit "Release Expense Document"; + CreateExpenseReport: Codeunit "Create Expense Report"; + begin + Expense.Get(Expense."No."); + ReleaseExpenseDocument.Run(Expense); + + CreateExpenseReport.AddSingleExpenseToExpenseReport(Expense, ExpenseReportHeader); + end; + + local procedure PostExpenseReport() + var + ExpenseReportHeader: Record "Expense Report Header"; + begin + if FromExpenseReportNo <> '' then + ExpenseReportHeader.SetFilter("No.", '>%1', FromExpenseReportNo); + + if ExpenseReportHeader.FindSet() then + repeat + Codeunit.Run(Codeunit::"Expense Report-Post", ExpenseReportHeader); + until ExpenseReportHeader.Next() = 0; + end; + + local procedure UpdateExpensePerDiem(ExpenseNo: Code[20]; LineNo: Integer; Breakfast: Boolean; Lunch: Boolean; Dinner: Boolean) + var + ExpensePerDiem: Record "Expense Per Diem"; + begin + ExpensePerDiem.Get(ExpenseNo, LineNo); + + ExpensePerDiem.Validate(Breakfast, Breakfast); + ExpensePerDiem.Validate(Lunch, Lunch); + ExpensePerDiem.Validate(Dinner, Dinner); + ExpensePerDiem.Modify(); + end; +} diff --git a/src/Apps/W1/ExpenseAgent/demo data/Country/FR/FRUpdEmpPostingGrp.Codeunit.al b/src/Apps/W1/ExpenseAgent/demo data/Country/FR/FRUpdEmpPostingGrp.Codeunit.al new file mode 100644 index 00000000000..9da17fbd6fd --- /dev/null +++ b/src/Apps/W1/ExpenseAgent/demo data/Country/FR/FRUpdEmpPostingGrp.Codeunit.al @@ -0,0 +1,32 @@ +// ------------------------------------------------------------------------------------------------ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. See License.txt in the project root for license information. +// ------------------------------------------------------------------------------------------------ +namespace Microsoft.ExpenseAgent; + +using Microsoft.DemoData.Finance; +using Microsoft.DemoData.HumanResources; + +codeunit 8303 "FR Upd. Emp. Posting Grp" +{ + InherentEntitlements = X; + InherentPermissions = X; + + trigger OnRun() + begin + UpdateEmployeePostingGroup(); + end; + + local procedure UpdateEmployeePostingGroup() + var + CreateGLAccount: Codeunit "Create G/L Account"; + ExpenseGLAccount: Codeunit "Create Expense G/L Account"; + FRExpGLAccount: Codeunit "FR Exp. GL Account"; + ContosoExpenseAgent: Codeunit "Contoso Expense Agent"; + CreateEmployeePostingGroup: Codeunit "Create Employee Posting Group"; + begin + ContosoExpenseAgent.SetOverwriteData(true); + ContosoExpenseAgent.UpdateEmployeePostingGroup(CreateEmployeePostingGroup.EmployeeExpenses(), ExpenseGLAccount.FindGLAccountByName(CreateGLAccount.EmployeesPayableName()), FRExpGLAccount.ExpensePrepaymentAccount(), ExpenseGLAccount.FindGLAccountByName(CreateGLAccount.BankLcyName()), FRExpGLAccount.CompanyCreditCards()); + ContosoExpenseAgent.SetOverwriteData(false); + end; +} diff --git a/src/Apps/W1/ExpenseAgent/demo data/Country/GB/GBCountryData.Codeunit.al b/src/Apps/W1/ExpenseAgent/demo data/Country/GB/GBCountryData.Codeunit.al new file mode 100644 index 00000000000..5fb2ca846cb --- /dev/null +++ b/src/Apps/W1/ExpenseAgent/demo data/Country/GB/GBCountryData.Codeunit.al @@ -0,0 +1,61 @@ +// ------------------------------------------------------------------------------------------------ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. See License.txt in the project root for license information. +// ------------------------------------------------------------------------------------------------ +namespace Microsoft.ExpenseAgent; + +codeunit 8234 "GB Country Data" implements "Expense Agent Country Data" +{ + Access = Internal; + InherentEntitlements = X; + InherentPermissions = X; + + procedure CreateSetupData() + var + W1CountryData: Codeunit "W1 Country Data"; + GBExpGLAccount: Codeunit "GB Exp. GL Account"; + GBExpPostingGrp: Codeunit "GB Exp. Posting Grp"; + begin + BindSubscription(GBExpGLAccount); + BindSubscription(GBExpPostingGrp); + + W1CountryData.CreateSetupData(); + Codeunit.Run(Codeunit::"GB Upd. Emp. Posting Grp"); + Codeunit.Run(Codeunit::"GB Exp. Posting Grp"); + + UnbindSubscription(GBExpPostingGrp); + UnbindSubscription(GBExpGLAccount); + end; + + procedure CreateMasterData() + var + W1CountryData: Codeunit "W1 Country Data"; + begin + W1CountryData.CreateMasterData(); + Codeunit.Run(Codeunit::"GB Exp. Categories"); + Codeunit.Run(Codeunit::"GB Exp. SubCategories"); + Codeunit.Run(Codeunit::"GB Exp. Rule Header"); + Codeunit.Run(Codeunit::"GB Exp. Rule Condition"); + end; + + procedure CreateTransactionalData() + var + W1CountryData: Codeunit "W1 Country Data"; + begin + W1CountryData.CreateTransactionalData(); + Codeunit.Run(Codeunit::"GB Expense"); + end; + + procedure CreateHistoricalData() + var + W1CountryData: Codeunit "W1 Country Data"; + GBPostedExpReport: Codeunit "GB Posted Exp. Report"; + begin + BindSubscription(GBPostedExpReport); + + W1CountryData.CreateHistoricalData(); + Codeunit.Run(Codeunit::"GB Posted Exp. Report"); + + UnbindSubscription(GBPostedExpReport); + end; +} diff --git a/src/Apps/W1/ExpenseAgent/demo data/Country/GB/GBExpCategories.Codeunit.al b/src/Apps/W1/ExpenseAgent/demo data/Country/GB/GBExpCategories.Codeunit.al new file mode 100644 index 00000000000..f054881cd68 --- /dev/null +++ b/src/Apps/W1/ExpenseAgent/demo data/Country/GB/GBExpCategories.Codeunit.al @@ -0,0 +1,31 @@ +// ------------------------------------------------------------------------------------------------ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. See License.txt in the project root for license information. +// ------------------------------------------------------------------------------------------------ +namespace Microsoft.ExpenseAgent; + +codeunit 8239 "GB Exp. Categories" +{ + InherentEntitlements = X; + InherentPermissions = X; + + trigger OnRun() + var + CreateExpenseGroup: Codeunit "Create Expense Group"; + CreateExpensePaymentMethod: Codeunit "Create Expense Payment Method"; + ContosoExpenseAgent: Codeunit "Contoso Expense Agent"; + GBExpPostingGrp: Codeunit "GB Exp. Posting Grp"; + begin + ContosoExpenseAgent.InsertExpenseCategory(PerDiem(), PerDiemByAssignedPolicyLbl, PerDiemByAssignedPolicyPostingLbl, GBExpPostingGrp.ExpensePerDiem(), Enum::"Expense Attachment Enforcement"::" ", CreateExpensePaymentMethod.Cash(), false, false, CreateExpenseGroup.Travel(), true, Enum::"Expense Reimbursement Type"::"Employee Paid", Enum::"Expense Detail Needed"::"Per Diem"); + end; + + var + PerDiemTok: Label 'PER-DIEM', MaxLength = 20, Locked = true; + PerDiemByAssignedPolicyLbl: Label 'Expenses for per-diem or daily allowance paid for business trips, typically based on travel itinerary or other proof of travel (e.g., booking or agenda), rather than individual expense receipts.', MaxLength = 250; + PerDiemByAssignedPolicyPostingLbl: Label 'Per-diem by assigned policy', MaxLength = 100; + + procedure PerDiem(): Code[20] + begin + exit(PerDiemTok); + end; +} diff --git a/src/Apps/W1/ExpenseAgent/demo data/Country/GB/GBExpGLAccount.Codeunit.al b/src/Apps/W1/ExpenseAgent/demo data/Country/GB/GBExpGLAccount.Codeunit.al new file mode 100644 index 00000000000..55aa053e6ff --- /dev/null +++ b/src/Apps/W1/ExpenseAgent/demo data/Country/GB/GBExpGLAccount.Codeunit.al @@ -0,0 +1,52 @@ +// ------------------------------------------------------------------------------------------------ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. See License.txt in the project root for license information. +// ------------------------------------------------------------------------------------------------ +namespace Microsoft.ExpenseAgent; + +using Microsoft.DemoTool.Helpers; +using Microsoft.Finance.GeneralLedger.Account; +using Microsoft.Foundation.Enums; + +codeunit 8236 "GB Exp. GL Account" +{ + SingleInstance = true; + EventSubscriberInstance = Manual; + InherentEntitlements = X; + InherentPermissions = X; + + [EventSubscriber(ObjectType::Codeunit, Codeunit::"Create Expense G/L Account", 'OnAfterAddGLAccountsForLocalization', '', false, false)] + local procedure ModifyGLAccount() + var + GLAccountCategory: Record "G/L Account Category"; + SubCategory: Text[80]; + begin + AddGLAccounts(); + + SubCategory := Format(GLAccountCategory."Account Category"::Assets, 80); + ContosoGLAccount.InsertGLAccount(ExpenseGLAccount.CompanyCreditCardsAccount(), ExpenseGLAccount.CompanyCreditCardsAccountName(), "G/L Account Income/Balance"::"Balance Sheet", Enum::"G/L Account Category"::Assets, SubCategory, Enum::"G/L Account Type"::Posting, '', '', '', 0, '', Enum::"General Posting Type"::" ", '', '', true, false, false); + + SubCategory := Format(GLAccountCategory."Account Category"::Expense, 80); + ContosoGLAccount.InsertGLAccount(ExpenseGLAccount.PerDiemTravelExpensesAccount(), ExpenseGLAccount.PerDiemTravelExpensesAccountName(), "G/L Account Income/Balance"::"Income Statement", Enum::"G/L Account Category"::Expense, SubCategory, Enum::"G/L Account Type"::Posting, '', '', '', 0, '', Enum::"General Posting Type"::Purchase, '', '', true, false, false); + ContosoGLAccount.InsertGLAccount(ExpenseGLAccount.MileageTravelExpensesAccount(), ExpenseGLAccount.MileageTravelExpensesAccountName(), "G/L Account Income/Balance"::"Income Statement", Enum::"G/L Account Category"::Expense, SubCategory, Enum::"G/L Account Type"::Posting, '', '', '', 0, '', Enum::"General Posting Type"::Purchase, '', '', true, false, false); + ContosoGLAccount.InsertGLAccount(ExpenseGLAccount.MealExpensesDeductibleAccount(), ExpenseGLAccount.MealExpensesDeductibleAccountName(), "G/L Account Income/Balance"::"Income Statement", Enum::"G/L Account Category"::Expense, SubCategory, Enum::"G/L Account Type"::Posting, '', '', '', 0, '', Enum::"General Posting Type"::Purchase, '', '', true, false, false); + ContosoGLAccount.InsertGLAccount(ExpenseGLAccount.MealExpensesNondeductibleAccount(), ExpenseGLAccount.MealExpensesNondeductibleAccountName(), "G/L Account Income/Balance"::"Income Statement", Enum::"G/L Account Category"::Expense, SubCategory, Enum::"G/L Account Type"::Posting, '', '', '', 0, '', Enum::"General Posting Type"::Purchase, '', '', true, false, false); + ContosoGLAccount.InsertGLAccount(ExpenseGLAccount.OtherNondeductibleTravelExpensesAccount(), ExpenseGLAccount.OtherNondeductibleTravelExpensesAccountName(), "G/L Account Income/Balance"::"Income Statement", Enum::"G/L Account Category"::Expense, SubCategory, Enum::"G/L Account Type"::Posting, '', '', '', 0, '', Enum::"General Posting Type"::Purchase, '', '', true, false, false); + ContosoGLAccount.InsertGLAccount(ExpenseGLAccount.MiscExternalExpensesNondeductibleAccount(), ExpenseGLAccount.MiscExternalExpensesNondeductibleAccountName(), "G/L Account Income/Balance"::"Income Statement", Enum::"G/L Account Category"::Expense, SubCategory, Enum::"G/L Account Type"::Posting, '', '', '', 0, '', Enum::"General Posting Type"::Purchase, '', '', true, false, false); + end; + + local procedure AddGLAccounts() + begin + ContosoGLAccount.AddAccountForLocalization(ExpenseGLAccount.CompanyCreditCardsAccountName(), '78410'); + ContosoGLAccount.AddAccountForLocalization(ExpenseGLAccount.PerDiemTravelExpensesAccountName(), '30550'); + ContosoGLAccount.AddAccountForLocalization(ExpenseGLAccount.MileageTravelExpensesAccountName(), '30560'); + ContosoGLAccount.AddAccountForLocalization(ExpenseGLAccount.MealExpensesDeductibleAccountName(), '30535'); + ContosoGLAccount.AddAccountForLocalization(ExpenseGLAccount.MealExpensesNondeductibleAccountName(), '30840'); + ContosoGLAccount.AddAccountForLocalization(ExpenseGLAccount.OtherNondeductibleTravelExpensesAccountName(), '30850'); + ContosoGLAccount.AddAccountForLocalization(ExpenseGLAccount.MiscExternalExpensesNondeductibleAccountName(), '31545'); + end; + + var + ContosoGLAccount: Codeunit "Contoso GL Account"; + ExpenseGLAccount: Codeunit "Create Expense G/L Account"; +} diff --git a/src/Apps/W1/ExpenseAgent/demo data/Country/GB/GBExpPostingGrp.Codeunit.al b/src/Apps/W1/ExpenseAgent/demo data/Country/GB/GBExpPostingGrp.Codeunit.al new file mode 100644 index 00000000000..9337c030760 --- /dev/null +++ b/src/Apps/W1/ExpenseAgent/demo data/Country/GB/GBExpPostingGrp.Codeunit.al @@ -0,0 +1,63 @@ +// ------------------------------------------------------------------------------------------------ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. See License.txt in the project root for license information. +// ------------------------------------------------------------------------------------------------ +namespace Microsoft.ExpenseAgent; + +codeunit 8237 "GB Exp. Posting Grp" +{ + SingleInstance = true; + EventSubscriberInstance = Manual; + InherentEntitlements = X; + InherentPermissions = X; + + trigger OnRun() + var + ContosoExpenseAgent: Codeunit "Contoso Expense Agent"; + begin + ContosoExpenseAgent.InsertExpensePostingGroup(ExpensePerDiem(), ExpensePerDiemLbl); + end; + + [EventSubscriber(ObjectType::Table, Database::"Expense Posting Group", 'OnBeforeInsertEvent', '', false, false)] + local procedure OnInsertRecord(var Rec: Record "Expense Posting Group") + var + GBGLAccountNames: Codeunit "GB GL Account Names"; + ExpenseGLAccount: Codeunit "Create Expense G/L Account"; + CreateExpensePostingGroup: Codeunit "Create Expense Posting Group"; + begin + case Rec.Code of + CreateExpensePostingGroup.ExpenseEntertainment(): + ValidateRecordFields(Rec, ExpenseGLAccount.FindGLAccountByName(GBGLAccountNames.BusinessEntertainingDeductibleName()), ExpenseGLAccount.FindGLAccountByName(GBGLAccountNames.OtherIncidentalRevenueName()), ExpenseGLAccount.FindGLAccountByName(GBGLAccountNames.OtherPrepaidExpensesAndAccruedIncomeName()), ExpenseGLAccount.FindGLAccountByName(GBGLAccountNames.PayableInvoiceRoundingName()), ExpenseGLAccount.FindGLAccountByName(GBGLAccountNames.PayableInvoiceRoundingName())); + CreateExpensePostingGroup.ExpenseMeals(): + ValidateRecordFields(Rec, ExpenseGLAccount.MealExpensesDeductibleAccount(), ExpenseGLAccount.FindGLAccountByName(GBGLAccountNames.OtherIncidentalRevenueName()), ExpenseGLAccount.FindGLAccountByName(GBGLAccountNames.OtherPrepaidExpensesAndAccruedIncomeName()), ExpenseGLAccount.FindGLAccountByName(GBGLAccountNames.PayableInvoiceRoundingName()), ExpenseGLAccount.FindGLAccountByName(GBGLAccountNames.PayableInvoiceRoundingName())); + CreateExpensePostingGroup.ExpenseMileage(): + ValidateRecordFields(Rec, ExpenseGLAccount.MileageTravelExpensesAccount(), '', ExpenseGLAccount.FindGLAccountByName(GBGLAccountNames.OtherPrepaidExpensesAndAccruedIncomeName()), ExpenseGLAccount.FindGLAccountByName(GBGLAccountNames.PayableInvoiceRoundingName()), ExpenseGLAccount.FindGLAccountByName(GBGLAccountNames.PayableInvoiceRoundingName())); + CreateExpensePostingGroup.ExpenseOther(): + ValidateRecordFields(Rec, ExpenseGLAccount.FindGLAccountByName(GBGLAccountNames.MiscExternalExpensesName()), ExpenseGLAccount.FindGLAccountByName(GBGLAccountNames.OtherIncidentalRevenueName()), ExpenseGLAccount.FindGLAccountByName(GBGLAccountNames.OtherPrepaidExpensesAndAccruedIncomeName()), ExpenseGLAccount.FindGLAccountByName(GBGLAccountNames.PayableInvoiceRoundingName()), ExpenseGLAccount.FindGLAccountByName(GBGLAccountNames.PayableInvoiceRoundingName())); + ExpensePerDiem(): + ValidateRecordFields(Rec, ExpenseGLAccount.PerDiemTravelExpensesAccount(), '', ExpenseGLAccount.FindGLAccountByName(GBGLAccountNames.OtherPrepaidExpensesAndAccruedIncomeName()), ExpenseGLAccount.FindGLAccountByName(GBGLAccountNames.PayableInvoiceRoundingName()), ExpenseGLAccount.FindGLAccountByName(GBGLAccountNames.PayableInvoiceRoundingName())); + CreateExpensePostingGroup.ExpenseTravel(): + ValidateRecordFields(Rec, ExpenseGLAccount.FindGLAccountByName(GBGLAccountNames.OtherTravelExpensesName()), ExpenseGLAccount.FindGLAccountByName(GBGLAccountNames.OtherIncidentalRevenueName()), ExpenseGLAccount.FindGLAccountByName(GBGLAccountNames.OtherPrepaidExpensesAndAccruedIncomeName()), ExpenseGLAccount.FindGLAccountByName(GBGLAccountNames.PayableInvoiceRoundingName()), ExpenseGLAccount.FindGLAccountByName(GBGLAccountNames.PayableInvoiceRoundingName())); + CreateExpensePostingGroup.ExpenseRentalCars(): + ValidateRecordFields(Rec, ExpenseGLAccount.FindGLAccountByName(GBGLAccountNames.RentalVehiclesName()), ExpenseGLAccount.FindGLAccountByName(GBGLAccountNames.OtherIncidentalRevenueName()), ExpenseGLAccount.FindGLAccountByName(GBGLAccountNames.OtherPrepaidExpensesAndAccruedIncomeName()), ExpenseGLAccount.FindGLAccountByName(GBGLAccountNames.PayableInvoiceRoundingName()), ExpenseGLAccount.FindGLAccountByName(GBGLAccountNames.PayableInvoiceRoundingName())); + end; + end; + + local procedure ValidateRecordFields(var ExpensePostingGroup: Record "Expense Posting Group"; RefundableDebitAccount: Code[20]; NonRefundableDebitAccount: Code[20]; PrepaymentCreditAccount: Code[20]; ExpenseDebitRoundingAccount: Code[20]; ExpenseCreditRoundingAccount: Code[20]) + begin + ExpensePostingGroup.Validate("Refundable Debit Account", RefundableDebitAccount); + ExpensePostingGroup.Validate("Non-Refundable Debit Account", NonRefundableDebitAccount); + ExpensePostingGroup.Validate("Prepayment Credit Account", PrepaymentCreditAccount); + ExpensePostingGroup.Validate("Debit Rounding Account", ExpenseDebitRoundingAccount); + ExpensePostingGroup.Validate("Credit Rounding Account", ExpenseCreditRoundingAccount); + end; + + var + ExpensePERDIEMTok: Label 'EXPENSE-PERDIEM', MaxLength = 20, Locked = true; + ExpensePerDiemLbl: Label 'Expense - Per Diem', MaxLength = 100; + + procedure ExpensePerDiem(): Code[20] + begin + exit(ExpensePERDIEMTok); + end; +} diff --git a/src/Apps/W1/ExpenseAgent/demo data/Country/GB/GBExpRuleCondition.Codeunit.al b/src/Apps/W1/ExpenseAgent/demo data/Country/GB/GBExpRuleCondition.Codeunit.al new file mode 100644 index 00000000000..c106f380a33 --- /dev/null +++ b/src/Apps/W1/ExpenseAgent/demo data/Country/GB/GBExpRuleCondition.Codeunit.al @@ -0,0 +1,26 @@ +// ------------------------------------------------------------------------------------------------ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. See License.txt in the project root for license information. +// ------------------------------------------------------------------------------------------------ +namespace Microsoft.ExpenseAgent; + +codeunit 8242 "GB Exp. Rule Condition" +{ + InherentEntitlements = X; + InherentPermissions = X; + + trigger OnRun() + var + GBExpCategories: Codeunit "GB Exp. Categories"; + CreateExpenseLocation: Codeunit "Create Expense Location"; + ContosoExpenseAgent: Codeunit "Contoso Expense Agent"; + begin + ContosoExpenseAgent.InsertExpenseRuleCondition(GBExpCategories.PerDiem(), CreateExpenseLocation.CanadaAll(), 0D, 10000, Enum::"Expense Rule Condition Type"::"Daily Rate", 125); + ContosoExpenseAgent.InsertExpenseRuleCondition(GBExpCategories.PerDiem(), CreateExpenseLocation.DenmarkAll(), 0D, 10000, Enum::"Expense Rule Condition Type"::"Daily Rate", 450); + ContosoExpenseAgent.InsertExpenseRuleCondition(GBExpCategories.PerDiem(), CreateExpenseLocation.Domestic(), 0D, 10000, Enum::"Expense Rule Condition Type"::"Daily Rate", 50); + ContosoExpenseAgent.InsertExpenseRuleCondition(GBExpCategories.PerDiem(), CreateExpenseLocation.FranceAll(), 0D, 10000, Enum::"Expense Rule Condition Type"::"Daily Rate", 110); + ContosoExpenseAgent.InsertExpenseRuleCondition(GBExpCategories.PerDiem(), CreateExpenseLocation.GermanyAll(), 0D, 10000, Enum::"Expense Rule Condition Type"::"Daily Rate", 105); + ContosoExpenseAgent.InsertExpenseRuleCondition(GBExpCategories.PerDiem(), CreateExpenseLocation.UKOther(), 0D, 10000, Enum::"Expense Rule Condition Type"::"Daily Rate", 115); + ContosoExpenseAgent.InsertExpenseRuleCondition(GBExpCategories.PerDiem(), CreateExpenseLocation.USAOther(), 0D, 10000, Enum::"Expense Rule Condition Type"::"Daily Rate", 120); + end; +} diff --git a/src/Apps/W1/ExpenseAgent/demo data/Country/GB/GBExpRuleHeader.Codeunit.al b/src/Apps/W1/ExpenseAgent/demo data/Country/GB/GBExpRuleHeader.Codeunit.al new file mode 100644 index 00000000000..bf8261c17f3 --- /dev/null +++ b/src/Apps/W1/ExpenseAgent/demo data/Country/GB/GBExpRuleHeader.Codeunit.al @@ -0,0 +1,29 @@ +// ------------------------------------------------------------------------------------------------ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. See License.txt in the project root for license information. +// ------------------------------------------------------------------------------------------------ +namespace Microsoft.ExpenseAgent; + +using Microsoft.DemoData.Finance; + +codeunit 8241 "GB Exp. Rule Header" +{ + InherentEntitlements = X; + InherentPermissions = X; + + trigger OnRun() + var + CreateCurrency: Codeunit "Create Currency"; + GBExpCategories: Codeunit "GB Exp. Categories"; + CreateExpenseLocation: Codeunit "Create Expense Location"; + ContosoExpenseAgent: Codeunit "Contoso Expense Agent"; + begin + ContosoExpenseAgent.InsertExpenseRuleHeader(GBExpCategories.PerDiem(), CreateExpenseLocation.CanadaAll(), 0D, Enum::"Expense Justification"::" ", false, '', CreateCurrency.CAD(), ''); + ContosoExpenseAgent.InsertExpenseRuleHeader(GBExpCategories.PerDiem(), CreateExpenseLocation.DenmarkAll(), 0D, Enum::"Expense Justification"::" ", false, '', CreateCurrency.EUR(), ''); + ContosoExpenseAgent.InsertExpenseRuleHeader(GBExpCategories.PerDiem(), CreateExpenseLocation.Domestic(), 0D, Enum::"Expense Justification"::" ", false, '', '', ''); + ContosoExpenseAgent.InsertExpenseRuleHeader(GBExpCategories.PerDiem(), CreateExpenseLocation.FranceAll(), 0D, Enum::"Expense Justification"::" ", false, '', CreateCurrency.EUR(), ''); + ContosoExpenseAgent.InsertExpenseRuleHeader(GBExpCategories.PerDiem(), CreateExpenseLocation.GermanyAll(), 0D, Enum::"Expense Justification"::" ", false, '', CreateCurrency.EUR(), ''); + ContosoExpenseAgent.InsertExpenseRuleHeader(GBExpCategories.PerDiem(), CreateExpenseLocation.UKOther(), 0D, Enum::"Expense Justification"::" ", false, '', '', ''); + ContosoExpenseAgent.InsertExpenseRuleHeader(GBExpCategories.PerDiem(), CreateExpenseLocation.USAOther(), 0D, Enum::"Expense Justification"::" ", false, '', '', ''); + end; +} diff --git a/src/Apps/W1/ExpenseAgent/demo data/Country/GB/GBExpSubCategories.Codeunit.al b/src/Apps/W1/ExpenseAgent/demo data/Country/GB/GBExpSubCategories.Codeunit.al new file mode 100644 index 00000000000..46a383cc9b7 --- /dev/null +++ b/src/Apps/W1/ExpenseAgent/demo data/Country/GB/GBExpSubCategories.Codeunit.al @@ -0,0 +1,39 @@ +// ------------------------------------------------------------------------------------------------ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. See License.txt in the project root for license information. +// ------------------------------------------------------------------------------------------------ +namespace Microsoft.ExpenseAgent; + +codeunit 8240 "GB Exp. SubCategories" +{ + InherentEntitlements = X; + InherentPermissions = X; + + trigger OnRun() + var + ContosoExpenseAgent: Codeunit "Contoso Expense Agent"; + GBExpCategories: Codeunit "GB Exp. Categories"; + begin + // PER-DIEM subcategories + ContosoExpenseAgent.InsertExpenseSubcategory(Country(), GBExpCategories.PerDiem(), LocalCountryPerDiemLbl, LocalCountryPerDiemPostingLbl, false, true, false); + ContosoExpenseAgent.InsertExpenseSubcategory(Intl(), GBExpCategories.PerDiem(), InternationalPerDiemLbl, InternationalPerDiemPostingLbl, false, true, false); + end; + + var + CountryTok: Label 'COUNTRY', MaxLength = 20, Locked = true; + IntlTok: Label 'INTL', MaxLength = 20, Locked = true; + LocalCountryPerDiemLbl: Label 'Daily per-diem allowance based on domestic travel rates, paid instead of individual meal or incidental expense reimbursements.', MaxLength = 250; + InternationalPerDiemLbl: Label 'Daily per-diem allowance for international business travel, based on applicable foreign travel rates.', MaxLength = 250; + LocalCountryPerDiemPostingLbl: Label 'Local country per-diem', MaxLength = 100; + InternationalPerDiemPostingLbl: Label 'International per-diem', MaxLength = 100; + + procedure Country(): Code[20] + begin + exit(CountryTok); + end; + + procedure Intl(): Code[20] + begin + exit(IntlTok); + end; +} diff --git a/src/Apps/W1/ExpenseAgent/demo data/Country/GB/GBExpense.Codeunit.al b/src/Apps/W1/ExpenseAgent/demo data/Country/GB/GBExpense.Codeunit.al new file mode 100644 index 00000000000..95bb196c26e --- /dev/null +++ b/src/Apps/W1/ExpenseAgent/demo data/Country/GB/GBExpense.Codeunit.al @@ -0,0 +1,51 @@ +// ------------------------------------------------------------------------------------------------ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. See License.txt in the project root for license information. +// ------------------------------------------------------------------------------------------------ +namespace Microsoft.ExpenseAgent; + +using Microsoft.DemoTool.Helpers; + +codeunit 8243 "GB Expense" +{ + InherentEntitlements = X; + InherentPermissions = X; + Permissions = tabledata "Expense Per Diem" = rim; + + trigger OnRun() + begin + CreateOpenExpense(); + end; + + local procedure CreateOpenExpense() + var + Expense: Record Expense; + ContosoExpenseAgent: Codeunit "Contoso Expense Agent"; + CreateExpenseLocation: Codeunit "Create Expense Location"; + begin + Expense := ContosoExpenseAgent.InsertExpense(CreateExpenseUser.EH(), GBExpCategories.PerDiem(), CreateExpenseLocation.DenmarkAll(), PerDiemByAssignedPolicyLbl, '', ContosoUtility.AdjustDate(19030203D), '', 0, '', CreateExpensePaymentMethod.Cash(), true, false, '', CreateDateTime(ContosoUtility.AdjustDate(19030115D), 144000T), CreateDateTime(ContosoUtility.AdjustDate(19030121D), 000500T), 0, 0, '', '', '', '', ''); + UpdateExpensePerDiem(Expense."No.", 10000, false, false, true); + UpdateExpensePerDiem(Expense."No.", 30000, false, true, false); + UpdateExpensePerDiem(Expense."No.", 40000, false, false, true); + UpdateExpensePerDiem(Expense."No.", 60000, false, true, true); + end; + + var + ContosoUtility: Codeunit "Contoso Utilities"; + CreateExpenseUser: Codeunit "Create Expense User"; + GBExpCategories: Codeunit "GB Exp. Categories"; + CreateExpensePaymentMethod: Codeunit "Create Expense Payment Method"; + PerDiemByAssignedPolicyLbl: Label 'Per-diem by assigned policy', MaxLength = 100; + + local procedure UpdateExpensePerDiem(ExpenseNo: Code[20]; LineNo: Integer; Breakfast: Boolean; Lunch: Boolean; Dinner: Boolean) + var + ExpensePerDiem: Record "Expense Per Diem"; + begin + ExpensePerDiem.Get(ExpenseNo, LineNo); + + ExpensePerDiem.Validate(Breakfast, Breakfast); + ExpensePerDiem.Validate(Lunch, Lunch); + ExpensePerDiem.Validate(Dinner, Dinner); + ExpensePerDiem.Modify(); + end; +} diff --git a/src/Apps/W1/ExpenseAgent/demo data/Country/GB/GBGLAccountNames.Codeunit.al b/src/Apps/W1/ExpenseAgent/demo data/Country/GB/GBGLAccountNames.Codeunit.al new file mode 100644 index 00000000000..c79a028f691 --- /dev/null +++ b/src/Apps/W1/ExpenseAgent/demo data/Country/GB/GBGLAccountNames.Codeunit.al @@ -0,0 +1,68 @@ +// ------------------------------------------------------------------------------------------------ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. See License.txt in the project root for license information. +// ------------------------------------------------------------------------------------------------ +namespace Microsoft.ExpenseAgent; + +codeunit 8235 "GB GL Account Names" +{ + Access = Internal; + InherentEntitlements = X; + InherentPermissions = X; + + var + BusinessEntertainingDeductibleTok: Label 'Business Entertaining, deductible', MaxLength = 100; + OtherIncidentalRevenueTok: Label 'Other Incidental Revenue', MaxLength = 100; + OtherPrepaidExpensesAndAccruedIncomeTok: Label 'Other prepaid expenses and accrued income', MaxLength = 100; + PayableInvoiceRoundingTok: Label 'Payable Invoice Rounding', MaxLength = 100; + MiscExternalExpensesTok: Label 'Misc. external expenses', MaxLength = 100; + OtherTravelExpensesTok: Label 'Other travel expenses', MaxLength = 100; + RentalVehiclesTok: Label 'Rental vehicles', MaxLength = 100; + OtherBankAccountsTok: Label 'Other bank accounts ', MaxLength = 100; + SaleofResourcesTok: Label 'Sale of Resources', MaxLength = 100; + + procedure BusinessEntertainingDeductibleName(): Text[100] + begin + exit(BusinessEntertainingDeductibleTok); + end; + + procedure OtherIncidentalRevenueName(): Text[100] + begin + exit(OtherIncidentalRevenueTok); + end; + + procedure OtherPrepaidExpensesAndAccruedIncomeName(): Text[100] + begin + exit(OtherPrepaidExpensesAndAccruedIncomeTok); + end; + + procedure PayableInvoiceRoundingName(): Text[100] + begin + exit(PayableInvoiceRoundingTok); + end; + + procedure MiscExternalExpensesName(): Text[100] + begin + exit(MiscExternalExpensesTok); + end; + + procedure OtherTravelExpensesName(): Text[100] + begin + exit(OtherTravelExpensesTok); + end; + + procedure RentalVehiclesName(): Text[100] + begin + exit(RentalVehiclesTok); + end; + + procedure OtherBankAccountsName(): Text[100] + begin + exit(OtherBankAccountsTok); + end; + + procedure SaleofResourcesName(): Text[100] + begin + exit(SaleofResourcesTok); + end; +} diff --git a/src/Apps/W1/ExpenseAgent/demo data/Country/GB/GBPostedExpReport.Codeunit.al b/src/Apps/W1/ExpenseAgent/demo data/Country/GB/GBPostedExpReport.Codeunit.al new file mode 100644 index 00000000000..5a05b6526c0 --- /dev/null +++ b/src/Apps/W1/ExpenseAgent/demo data/Country/GB/GBPostedExpReport.Codeunit.al @@ -0,0 +1,168 @@ +// ------------------------------------------------------------------------------------------------ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. See License.txt in the project root for license information. +// ------------------------------------------------------------------------------------------------ +namespace Microsoft.ExpenseAgent; + +using Microsoft.DemoData.Finance; +using Microsoft.DemoData.HumanResources; +using Microsoft.DemoTool.Helpers; + +codeunit 8244 "GB Posted Exp. Report" +{ + SingleInstance = true; + EventSubscriberInstance = Manual; + InherentEntitlements = X; + InherentPermissions = X; + Permissions = + tabledata "Expense Per Diem" = rim, + tabledata "Expense Report Line" = rim; + + trigger OnRun() + var + ExpenseReportHeader: Record "Expense Report Header"; + begin + if ExpenseReportHeader.FindLast() then + FromExpenseReportNo := ExpenseReportHeader."No."; + + CreateExpenseReportToPost(); + + PostExpenseReport(); + end; + + [EventSubscriber(ObjectType::Codeunit, Codeunit::"Create Posted Expense Report", OnDefineExpenseAccountNo, '', false, false)] + local procedure OnDefineExpenseAccountNo(var AccountNo: Code[20]) + var + GBGLAccountNames: Codeunit "GB GL Account Names"; + ExpenseGLAccount: Codeunit "Create Expense G/L Account"; + begin + AccountNo := ExpenseGLAccount.FindGLAccountByName(GBGLAccountNames.SaleofResourcesName()); + end; + + local procedure CreateExpenseReportToPost() + var + Expense: Record Expense; + ExpenseReportHeader: Record "Expense Report Header"; + CreateEmployee: Codeunit "Create Employee"; + CreateCurrency: Codeunit "Create Currency"; + ContosoUtility: Codeunit "Contoso Utilities"; + CreateExpenseUser: Codeunit "Create Expense User"; + CreateExpenseLocation: Codeunit "Create Expense Location"; + ContosoExpenseAgent: Codeunit "Contoso Expense Agent"; + CreateExpCategories: Codeunit "Create Expense Categories DM"; + GBExpCategories: Codeunit "GB Exp. Categories"; + CreateExpenseSubcategories: Codeunit "Create Expense Subcategories"; + CreateExpensePaymentMethod: Codeunit "Create Expense Payment Method"; + begin + ExpenseReportHeader := ContosoExpenseAgent.InsertExpenseReportHeader(CreateExpenseUser.JO(), ContosoUtility.AdjustDate(19021104D), ContosoUtility.AdjustDate(19021104D)); + Expense := ContosoExpenseAgent.InsertExpense(CreateExpenseUser.JO(), GBExpCategories.PerDiem(), CreateExpenseLocation.GermanyAll(), BusinessTripToHamburgLbl, '', ContosoUtility.AdjustDate(19021103D), '', 0, '', CreateExpensePaymentMethod.Cash(), true, false, '', CreateDateTime(ContosoUtility.AdjustDate(19021024D), 064500T), CreateDateTime(ContosoUtility.AdjustDate(19021027D), 161500T), 0, 0, '', '', '', '', ''); + ReleaseAndAddExpenseToExpenseReport(Expense, ExpenseReportHeader); + Expense := ContosoExpenseAgent.InsertExpense(CreateExpenseUser.JO(), CreateExpCategories.Airline(), '', AirlineTicketsLbl, '', ContosoUtility.AdjustDate(19021010D), '', 2042, MargieTravelLbl, CreateExpensePaymentMethod.Card(), true, false, '', 0DT, 0DT, 0, 0, '', '', 'TY6HJO', '', ''); + ReleaseAndAddExpenseToExpenseReport(Expense, ExpenseReportHeader); + + ExpenseReportHeader := ContosoExpenseAgent.InsertExpenseReportHeader(CreateExpenseUser.EH(), ContosoUtility.AdjustDate(19021204D), ContosoUtility.AdjustDate(19021204D)); + Expense := ContosoExpenseAgent.InsertExpense(CreateExpenseUser.EH(), CreateExpCategories.Airline(), '', AirlineTicketsDublinLbl, TravelToConferenceLbl, ContosoUtility.AdjustDate(19021106D), '', 3120, MargieTravelLbl, CreateExpensePaymentMethod.Card(), true, false, '', 0DT, 0DT, 0, 0, '', '', 'FIUXHJT', '', ''); + ReleaseAndAddExpenseToExpenseReport(Expense, ExpenseReportHeader); + Expense := ContosoExpenseAgent.InsertExpense(CreateExpenseUser.EH(), CreateExpCategories.Events(), '', ITConferenceLbl, '', ContosoUtility.AdjustDate(19021107D), CreateCurrency.EUR(), 1990, ProsewareIncLbl, CreateExpensePaymentMethod.Card(), true, false, '', 0DT, 0DT, 0, 0, '', '', 'G574576HJ656', '', ''); + ReleaseAndAddExpenseToExpenseReport(Expense, ExpenseReportHeader); + Expense := ContosoExpenseAgent.InsertExpense(CreateExpenseUser.EH(), CreateExpCategories.GroundTransportation(), '', TaxiLbl, '', ContosoUtility.AdjustDate(19021114D), CreateCurrency.EUR(), 45, TailwindTradersLbl, CreateExpensePaymentMethod.Cash(), true, false, '', 0DT, 0DT, 0, 0, '', '', '456845856867', '', ''); + ReleaseAndAddExpenseToExpenseReport(Expense, ExpenseReportHeader); + Expense := ContosoExpenseAgent.InsertExpense(CreateExpenseUser.EH(), CreateExpCategories.Entertain(), '', BusinessDinnerLbl, BusinessDinnerWithBigPotentialCustomersLbl, ContosoUtility.AdjustDate(19021116D), CreateCurrency.EUR(), 842, FourthCoffeeLbl, CreateExpensePaymentMethod.Card(), true, false, '', 0DT, 0DT, 0, 0, '', '', 'RT6457560034', '', ''); + ContosoExpenseAgent.InsertExpenseParticipant(Expense."No.", 10000, CreateExpCategories.Entertain(), Enum::"Expense Participant Type"::Employee, CreateEmployee.ManagingDirector(), '', '', '', '', ''); + ContosoExpenseAgent.InsertExpenseParticipant(Expense."No.", 20000, CreateExpCategories.Entertain(), Enum::"Expense Participant Type"::Employee, CreateEmployee.SalesManager(), '', '', '', '', ''); + ContosoExpenseAgent.InsertExpenseParticipant(Expense."No.", 30000, CreateExpCategories.Entertain(), Enum::"Expense Participant Type"::External, '', JesseHomerLbl, RelecloudLbl, '', CEOLbl, 'jesse.homer@contoso.com'); + ContosoExpenseAgent.InsertExpenseParticipant(Expense."No.", 40000, CreateExpCategories.Entertain(), Enum::"Expense Participant Type"::External, '', RobertTownesLbl, AdatumCorporationLbl, '', CEOLbl, 'robert.townes@contoso.com'); + ReleaseAndAddExpenseToExpenseReport(Expense, ExpenseReportHeader); + Expense := ContosoExpenseAgent.InsertExpense(CreateExpenseUser.EH(), CreateExpCategories.Hotels(), '', HotelStayLbl, '', ContosoUtility.AdjustDate(19021118D), CreateCurrency.EUR(), 2150, ContosoSuitesLbl, CreateExpensePaymentMethod.Card(), true, false, '', 0DT, 0DT, 0, 0, '', '', '64675S879CT987990004', '', ''); + ContosoExpenseAgent.InsertExpenseItemization(Expense."No.", 10000, CreateExpCategories.Hotels(), CreateExpenseSubcategories.Room(), AccommodationLbl, ContosoUtility.AdjustDate(19021114D), 390); + ContosoExpenseAgent.InsertExpenseItemization(Expense."No.", 20000, CreateExpCategories.Hotels(), CreateExpenseSubcategories.Breakfast(), BreakfastLbl, ContosoUtility.AdjustDate(19021115D), 35); + ContosoExpenseAgent.InsertExpenseItemization(Expense."No.", 30000, CreateExpCategories.Hotels(), CreateExpenseSubcategories.Room(), AccommodationLbl, ContosoUtility.AdjustDate(19021115D), 390); + ContosoExpenseAgent.InsertExpenseItemization(Expense."No.", 40000, CreateExpCategories.Hotels(), CreateExpenseSubcategories.Breakfast(), BreakfastLbl, ContosoUtility.AdjustDate(19021116D), 35); + ContosoExpenseAgent.InsertExpenseItemization(Expense."No.", 50000, CreateExpCategories.Hotels(), CreateExpenseSubcategories.Room(), AccommodationLbl, ContosoUtility.AdjustDate(19021116D), 390); + ContosoExpenseAgent.InsertExpenseItemization(Expense."No.", 60000, CreateExpCategories.Hotels(), CreateExpenseSubcategories.RoomService(), RoomServiceLbl, ContosoUtility.AdjustDate(19021116D), 145); + ContosoExpenseAgent.InsertExpenseItemization(Expense."No.", 70000, CreateExpCategories.Hotels(), CreateExpenseSubcategories.Breakfast(), BreakfastLbl, ContosoUtility.AdjustDate(19021117D), 35); + ContosoExpenseAgent.InsertExpenseItemization(Expense."No.", 80000, CreateExpCategories.Hotels(), CreateExpenseSubcategories.Room(), AccommodationLbl, ContosoUtility.AdjustDate(19021117D), 390); + ContosoExpenseAgent.InsertExpenseItemization(Expense."No.", 90000, CreateExpCategories.Hotels(), CreateExpenseSubcategories.Breakfast(), BreakfastLbl, ContosoUtility.AdjustDate(19021118D), 35); + ContosoExpenseAgent.InsertExpenseItemization(Expense."No.", 100000, CreateExpCategories.Hotels(), CreateExpenseSubcategories.Tax(), HotelTaxesLbl, ContosoUtility.AdjustDate(19021118D), 305); + ReleaseAndAddExpenseToExpenseReport(Expense, ExpenseReportHeader); + Expense := ContosoExpenseAgent.InsertExpense(CreateExpenseUser.EH(), CreateExpCategories.RentalCars(), '', CarRentalsLbl, '', ContosoUtility.AdjustDate(19021118D), CreateCurrency.EUR(), 622.45, VanArsdelLtdLbl, CreateExpensePaymentMethod.Card(), true, false, '', 0DT, 0DT, 0, 0, '', '', 'H6584769867J9J95789', '', ''); + ReleaseAndAddExpenseToExpenseReport(Expense, ExpenseReportHeader); + Expense := ContosoExpenseAgent.InsertExpense(CreateExpenseUser.EH(), CreateExpCategories.GroundTransportation(), '', TaxiLbl, '', ContosoUtility.AdjustDate(19021118D), CreateCurrency.EUR(), 71, TailwindTradersLbl, CreateExpensePaymentMethod.Cash(), true, false, '', 0DT, 0DT, 0, 0, '', '', '7456875687568', '', ''); + ReleaseAndAddExpenseToExpenseReport(Expense, ExpenseReportHeader); + Expense := ContosoExpenseAgent.InsertExpense(CreateExpenseUser.EH(), GBExpCategories.PerDiem(), CreateExpenseLocation.UKOther(), TripToUKLbl, '', ContosoUtility.AdjustDate(19021121D), '', 0, '', CreateExpensePaymentMethod.Cash(), true, false, '', CreateDateTime(ContosoUtility.AdjustDate(19021114D), 053000T), CreateDateTime(ContosoUtility.AdjustDate(19021118D), 220500T), 0, 0, '', '', '', '', ''); + UpdateExpensePerDiem(Expense."No.", 20000, false, false, true); + UpdateExpensePerDiem(Expense."No.", 40000, false, true, false); + ReleaseAndAddExpenseToExpenseReport(Expense, ExpenseReportHeader); + Expense := ContosoExpenseAgent.InsertExpense(CreateExpenseUser.EH(), GBExpCategories.PerDiem(), CreateExpenseLocation.Domestic(), TripToDoverLbl, '', ContosoUtility.AdjustDate(19021204D), '', 0, '', CreateExpensePaymentMethod.Cash(), true, false, '', CreateDateTime(ContosoUtility.AdjustDate(19021127D), 070000T), CreateDateTime(ContosoUtility.AdjustDate(19021129D), 145500T), 0, 0, '', '', '', '', ''); + ReleaseAndAddExpenseToExpenseReport(Expense, ExpenseReportHeader); + Expense := ContosoExpenseAgent.InsertExpense(CreateExpenseUser.EH(), CreateExpCategories.Mileage(), '', MileageLbl, '', ContosoUtility.AdjustDate(19031101D), '', 0, VanArsdelLtdLbl, CreateExpensePaymentMethod.Cash(), true, false, '', 0DT, 0DT, 0, 249, 'New York', 'Dover', 'H6584769867J9J95789', '', ''); + ReleaseAndAddExpenseToExpenseReport(Expense, ExpenseReportHeader); + end; + + var + FromExpenseReportNo: Code[20]; + BusinessTripToHamburgLbl: Label 'Business trip to Hamburg, DE', MaxLength = 100; + AirlineTicketsLbl: Label 'Airline tickets NY/FRANKFURT/HAMBURG/FRANKFURT/NY', MaxLength = 100; + MargieTravelLbl: Label 'Margie''s Travel', MaxLength = 100; + AirlineTicketsDublinLbl: Label 'Airline tickets NY/DUBLIN/NY', MaxLength = 100; + TravelToConferenceLbl: Label 'Travel to the conference', MaxLength = 100; + ITConferenceLbl: Label 'IT Conference', MaxLength = 100; + ProsewareIncLbl: Label 'Proseware, Inc.', MaxLength = 100; + TaxiLbl: Label 'Taxi', MaxLength = 100; + TailwindTradersLbl: Label 'Tailwind Traders', MaxLength = 100; + BusinessDinnerLbl: Label 'Business Dinner', MaxLength = 100; + BusinessDinnerWithBigPotentialCustomersLbl: Label 'Business dinner with a big potential customers', MaxLength = 100; + FourthCoffeeLbl: Label 'Fourth Coffee', MaxLength = 100; + JesseHomerLbl: Label 'Jesse Homer', MaxLength = 100; + RelecloudLbl: Label 'Relecloud', MaxLength = 100; + RobertTownesLbl: Label 'Robert Townes', MaxLength = 100; + AdatumCorporationLbl: Label 'Adatum Corporation', MaxLength = 100; + HotelStayLbl: Label 'Hotel stay', MaxLength = 100; + ContosoSuitesLbl: Label 'Contoso Suites', MaxLength = 100; + AccommodationLbl: Label 'Accommodation', MaxLength = 100; + BreakfastLbl: Label 'Breakfast', MaxLength = 100; + HotelTaxesLbl: Label 'Hotel Taxes', MaxLength = 100; + RoomServiceLbl: Label 'Room service', MaxLength = 100; + CarRentalsLbl: Label 'Car Rentals', MaxLength = 100; + VanArsdelLtdLbl: Label 'VanArsdel, Ltd.', MaxLength = 100; + TripToUKLbl: Label 'Trip to UK', MaxLength = 100; + TripToDoverLbl: Label 'Trip to Dover', MaxLength = 100; + MileageLbl: Label 'Mileage', MaxLength = 100; + CEOLbl: Label 'CEO', MaxLength = 30; + + local procedure ReleaseAndAddExpenseToExpenseReport(Expense: Record Expense; ExpenseReportHeader: Record "Expense Report Header") + var + ReleaseExpenseDocument: Codeunit "Release Expense Document"; + CreateExpenseReport: Codeunit "Create Expense Report"; + begin + Expense.Get(Expense."No."); + ReleaseExpenseDocument.Run(Expense); + + CreateExpenseReport.AddSingleExpenseToExpenseReport(Expense, ExpenseReportHeader); + end; + + local procedure PostExpenseReport() + var + ExpenseReportHeader: Record "Expense Report Header"; + begin + if FromExpenseReportNo <> '' then + ExpenseReportHeader.SetFilter("No.", '>%1', FromExpenseReportNo); + + if ExpenseReportHeader.FindSet() then + repeat + Codeunit.Run(Codeunit::"Expense Report-Post", ExpenseReportHeader); + until ExpenseReportHeader.Next() = 0; + end; + + local procedure UpdateExpensePerDiem(ExpenseNo: Code[20]; LineNo: Integer; Breakfast: Boolean; Lunch: Boolean; Dinner: Boolean) + var + ExpensePerDiem: Record "Expense Per Diem"; + begin + ExpensePerDiem.Get(ExpenseNo, LineNo); + + ExpensePerDiem.Validate(Breakfast, Breakfast); + ExpensePerDiem.Validate(Lunch, Lunch); + ExpensePerDiem.Validate(Dinner, Dinner); + ExpensePerDiem.Modify(); + end; +} diff --git a/src/Apps/W1/ExpenseAgent/demo data/Country/GB/GBUpdEmpPostingGrp.Codeunit.al b/src/Apps/W1/ExpenseAgent/demo data/Country/GB/GBUpdEmpPostingGrp.Codeunit.al new file mode 100644 index 00000000000..51a9072c619 --- /dev/null +++ b/src/Apps/W1/ExpenseAgent/demo data/Country/GB/GBUpdEmpPostingGrp.Codeunit.al @@ -0,0 +1,32 @@ +// ------------------------------------------------------------------------------------------------ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. See License.txt in the project root for license information. +// ------------------------------------------------------------------------------------------------ +namespace Microsoft.ExpenseAgent; + +using Microsoft.DemoData.Finance; +using Microsoft.DemoData.HumanResources; + +codeunit 8238 "GB Upd. Emp. Posting Grp" +{ + InherentEntitlements = X; + InherentPermissions = X; + + trigger OnRun() + begin + UpdateEmployeePostingGroup(); + end; + + local procedure UpdateEmployeePostingGroup() + var + CreateGLAccount: Codeunit "Create G/L Account"; + ExpenseGLAccount: Codeunit "Create Expense G/L Account"; + GBGLAccountNames: Codeunit "GB GL Account Names"; + ContosoExpenseAgent: Codeunit "Contoso Expense Agent"; + CreateEmployeePostingGroup: Codeunit "Create Employee Posting Group"; + begin + ContosoExpenseAgent.SetOverwriteData(true); + ContosoExpenseAgent.UpdateEmployeePostingGroup(CreateEmployeePostingGroup.EmployeeExpenses(), ExpenseGLAccount.FindGLAccountByName(CreateGLAccount.EmployeesPayableName()), ExpenseGLAccount.FindGLAccountByName(CreateGLAccount.CashName()), ExpenseGLAccount.FindGLAccountByName(GBGLAccountNames.OtherBankAccountsName()), ExpenseGLAccount.CompanyCreditCardsAccount()); + ContosoExpenseAgent.SetOverwriteData(false); + end; +} diff --git a/src/Apps/W1/ExpenseAgent/demo data/Country/NZ/NZCountryData.Codeunit.al b/src/Apps/W1/ExpenseAgent/demo data/Country/NZ/NZCountryData.Codeunit.al new file mode 100644 index 00000000000..61c4dee22b4 --- /dev/null +++ b/src/Apps/W1/ExpenseAgent/demo data/Country/NZ/NZCountryData.Codeunit.al @@ -0,0 +1,61 @@ +// ------------------------------------------------------------------------------------------------ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. See License.txt in the project root for license information. +// ------------------------------------------------------------------------------------------------ +namespace Microsoft.ExpenseAgent; + +codeunit 8255 "NZ Country Data" implements "Expense Agent Country Data" +{ + Access = Internal; + InherentEntitlements = X; + InherentPermissions = X; + + procedure CreateSetupData() + var + W1CountryData: Codeunit "W1 Country Data"; + NZExpGLAccount: Codeunit "NZ Exp. GL Account"; + NZExpPostingGrp: Codeunit "NZ Exp. Posting Grp"; + begin + BindSubscription(NZExpGLAccount); + BindSubscription(NZExpPostingGrp); + + W1CountryData.CreateSetupData(); + Codeunit.Run(Codeunit::"NZ Upd. Emp. Posting Grp"); + Codeunit.Run(Codeunit::"NZ Exp. Posting Grp"); + + UnbindSubscription(NZExpPostingGrp); + UnbindSubscription(NZExpGLAccount); + end; + + procedure CreateMasterData() + var + W1CountryData: Codeunit "W1 Country Data"; + begin + W1CountryData.CreateMasterData(); + Codeunit.Run(Codeunit::"NZ Exp. Categories"); + Codeunit.Run(Codeunit::"NZ Exp. SubCategories"); + Codeunit.Run(Codeunit::"NZ Exp. Rule Header"); + Codeunit.Run(Codeunit::"NZ Exp. Rule Condition"); + end; + + procedure CreateTransactionalData() + var + W1CountryData: Codeunit "W1 Country Data"; + begin + W1CountryData.CreateTransactionalData(); + Codeunit.Run(Codeunit::"NZ Expense"); + end; + + procedure CreateHistoricalData() + var + W1CountryData: Codeunit "W1 Country Data"; + NZPostedExpReport: Codeunit "NZ Posted Exp. Report"; + begin + BindSubscription(NZPostedExpReport); + + W1CountryData.CreateHistoricalData(); + Codeunit.Run(Codeunit::"NZ Posted Exp. Report"); + + UnbindSubscription(NZPostedExpReport); + end; +} diff --git a/src/Apps/W1/ExpenseAgent/demo data/Country/NZ/NZExpCategories.Codeunit.al b/src/Apps/W1/ExpenseAgent/demo data/Country/NZ/NZExpCategories.Codeunit.al new file mode 100644 index 00000000000..4b2bf7403cb --- /dev/null +++ b/src/Apps/W1/ExpenseAgent/demo data/Country/NZ/NZExpCategories.Codeunit.al @@ -0,0 +1,31 @@ +// ------------------------------------------------------------------------------------------------ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. See License.txt in the project root for license information. +// ------------------------------------------------------------------------------------------------ +namespace Microsoft.ExpenseAgent; + +codeunit 8259 "NZ Exp. Categories" +{ + InherentEntitlements = X; + InherentPermissions = X; + + trigger OnRun() + var + CreateExpenseGroup: Codeunit "Create Expense Group"; + CreateExpensePaymentMethod: Codeunit "Create Expense Payment Method"; + ContosoExpenseAgent: Codeunit "Contoso Expense Agent"; + NZExpPostingGrp: Codeunit "NZ Exp. Posting Grp"; + begin + ContosoExpenseAgent.InsertExpenseCategory(PerDiem(), PerDiemByAssignedPolicyLbl, PerDiemByAssignedPolicyPostingLbl, NZExpPostingGrp.ExpensePerDiem(), Enum::"Expense Attachment Enforcement"::" ", CreateExpensePaymentMethod.Cash(), false, false, CreateExpenseGroup.Travel(), true, Enum::"Expense Reimbursement Type"::"Employee Paid", Enum::"Expense Detail Needed"::"Per Diem"); + end; + + var + PerDiemTok: Label 'PER-DIEM', MaxLength = 20, Locked = true; + PerDiemByAssignedPolicyLbl: Label 'Expenses for per-diem or daily allowance paid for business trips, typically based on travel itinerary or other proof of travel (e.g., booking or agenda), rather than individual expense receipts.', MaxLength = 250; + PerDiemByAssignedPolicyPostingLbl: Label 'Per-diem by assigned policy', MaxLength = 100; + + procedure PerDiem(): Code[20] + begin + exit(PerDiemTok); + end; +} diff --git a/src/Apps/W1/ExpenseAgent/demo data/Country/NZ/NZExpGLAccount.Codeunit.al b/src/Apps/W1/ExpenseAgent/demo data/Country/NZ/NZExpGLAccount.Codeunit.al new file mode 100644 index 00000000000..37b76823dce --- /dev/null +++ b/src/Apps/W1/ExpenseAgent/demo data/Country/NZ/NZExpGLAccount.Codeunit.al @@ -0,0 +1,60 @@ +// ------------------------------------------------------------------------------------------------ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. See License.txt in the project root for license information. +// ------------------------------------------------------------------------------------------------ +namespace Microsoft.ExpenseAgent; + +using Microsoft.DemoTool.Helpers; +using Microsoft.Finance.GeneralLedger.Account; +using Microsoft.Foundation.Enums; + +codeunit 8256 "NZ Exp. GL Account" +{ + SingleInstance = true; + EventSubscriberInstance = Manual; + InherentEntitlements = X; + InherentPermissions = X; + + [EventSubscriber(ObjectType::Codeunit, Codeunit::"Create Expense G/L Account", 'OnAfterAddGLAccountsForLocalization', '', false, false)] + local procedure ModifyGLAccount() + var + GLAccountCategory: Record "G/L Account Category"; + SubCategory: Text[80]; + begin + AddGLAccounts(); + + SubCategory := Format(GLAccountCategory."Account Category"::Assets, 80); + ContosoGLAccount.InsertGLAccount(ExpenseGLAccount.CompanyCreditCardsAccount(), ExpenseGLAccount.CompanyCreditCardsAccountName(), "G/L Account Income/Balance"::"Balance Sheet", Enum::"G/L Account Category"::Assets, SubCategory, Enum::"G/L Account Type"::Posting, '', '', '', 0, '', Enum::"General Posting Type"::" ", '', '', true, false, false); + ContosoGLAccount.InsertGLAccount(ExpenseGLAccount.EmployeePrepaymentsAccount(), ExpenseGLAccount.EmployeePrepaymentsAccountName(), "G/L Account Income/Balance"::"Balance Sheet", Enum::"G/L Account Category"::Assets, SubCategory, Enum::"G/L Account Type"::"Begin-Total", '', '', '', 0, '', Enum::"General Posting Type"::" ", '', '', false, false, false); + ContosoGLAccount.InsertGLAccount(ExpenseGLAccount.EmployeePrepaymentsExpensesAccount(), ExpenseGLAccount.EmployeePrepaymentsExpensesAccountName(), "G/L Account Income/Balance"::"Balance Sheet", Enum::"G/L Account Category"::Assets, SubCategory, Enum::"G/L Account Type"::Posting, '', '', '', 0, '', Enum::"General Posting Type"::" ", '', '', true, false, false); + ContosoGLAccount.InsertGLAccount(ExpenseGLAccount.EmployeePrepaymentsTotalAccount(), ExpenseGLAccount.EmployeePrepaymentsTotalAccountName(), "G/L Account Income/Balance"::"Balance Sheet", Enum::"G/L Account Category"::Assets, SubCategory, Enum::"G/L Account Type"::"End-Total", '', '', '', 0, ExpenseGLAccount.EmployeePrepaymentsAccount() + '..' + ExpenseGLAccount.EmployeePrepaymentsTotalAccount(), Enum::"General Posting Type"::" ", '', '', false, false, false); + + SubCategory := Format(GLAccountCategory."Account Category"::Expense, 80); + ContosoGLAccount.InsertGLAccount(ExpenseGLAccount.PerDiemTravelExpensesAccount(), ExpenseGLAccount.PerDiemTravelExpensesAccountName(), "G/L Account Income/Balance"::"Income Statement", Enum::"G/L Account Category"::Expense, SubCategory, Enum::"G/L Account Type"::Posting, '', '', '', 0, '', Enum::"General Posting Type"::Purchase, '', '', true, false, false); + ContosoGLAccount.InsertGLAccount(ExpenseGLAccount.MileageTravelExpensesAccount(), ExpenseGLAccount.MileageTravelExpensesAccountName(), "G/L Account Income/Balance"::"Income Statement", Enum::"G/L Account Category"::Expense, SubCategory, Enum::"G/L Account Type"::Posting, '', '', '', 0, '', Enum::"General Posting Type"::Purchase, '', '', true, false, false); + ContosoGLAccount.InsertGLAccount(ExpenseGLAccount.MealExpensesDeductibleAccount(), ExpenseGLAccount.MealExpensesDeductibleAccountName(), "G/L Account Income/Balance"::"Income Statement", Enum::"G/L Account Category"::Expense, SubCategory, Enum::"G/L Account Type"::Posting, '', '', '', 0, '', Enum::"General Posting Type"::Purchase, '', '', true, false, false); + ContosoGLAccount.InsertGLAccount(ExpenseGLAccount.MealExpensesNondeductibleAccount(), ExpenseGLAccount.MealExpensesNondeductibleAccountName(), "G/L Account Income/Balance"::"Income Statement", Enum::"G/L Account Category"::Expense, SubCategory, Enum::"G/L Account Type"::Posting, '', '', '', 0, '', Enum::"General Posting Type"::Purchase, '', '', true, false, false); + ContosoGLAccount.InsertGLAccount(ExpenseGLAccount.OtherNondeductibleTravelExpensesAccount(), ExpenseGLAccount.OtherNondeductibleTravelExpensesAccountName(), "G/L Account Income/Balance"::"Income Statement", Enum::"G/L Account Category"::Expense, SubCategory, Enum::"G/L Account Type"::Posting, '', '', '', 0, '', Enum::"General Posting Type"::Purchase, '', '', true, false, false); + ContosoGLAccount.InsertGLAccount(ExpenseGLAccount.MiscExternalExpensesNondeductibleAccount(), ExpenseGLAccount.MiscExternalExpensesNondeductibleAccountName(), "G/L Account Income/Balance"::"Income Statement", Enum::"G/L Account Category"::Expense, SubCategory, Enum::"G/L Account Type"::Posting, '', '', '', 0, '', Enum::"General Posting Type"::Purchase, '', '', true, false, false); + ContosoGLAccount.InsertGLAccount(ExpenseGLAccount.RentalVehiclesAccount(), ExpenseGLAccount.RentalVehiclesAccountName(), "G/L Account Income/Balance"::"Income Statement", Enum::"G/L Account Category"::Expense, SubCategory, Enum::"G/L Account Type"::Posting, '', '', '', 0, '', Enum::"General Posting Type"::Purchase, '', '', true, false, false); + end; + + local procedure AddGLAccounts() + begin + ContosoGLAccount.AddAccountForLocalization(ExpenseGLAccount.CompanyCreditCardsAccountName(), '2950'); + ContosoGLAccount.AddAccountForLocalization(ExpenseGLAccount.EmployeePrepaymentsAccountName(), '2500'); + ContosoGLAccount.AddAccountForLocalization(ExpenseGLAccount.EmployeePrepaymentsExpensesAccountName(), '2510'); + ContosoGLAccount.AddAccountForLocalization(ExpenseGLAccount.EmployeePrepaymentsTotalAccountName(), '2590'); + ContosoGLAccount.AddAccountForLocalization(ExpenseGLAccount.PerDiemTravelExpensesAccountName(), '8431'); + ContosoGLAccount.AddAccountForLocalization(ExpenseGLAccount.MileageTravelExpensesAccountName(), '8432'); + ContosoGLAccount.AddAccountForLocalization(ExpenseGLAccount.MealExpensesDeductibleAccountName(), '8433'); + ContosoGLAccount.AddAccountForLocalization(ExpenseGLAccount.MealExpensesNondeductibleAccountName(), '8421'); + ContosoGLAccount.AddAccountForLocalization(ExpenseGLAccount.OtherNondeductibleTravelExpensesAccountName(), '8650'); + ContosoGLAccount.AddAccountForLocalization(ExpenseGLAccount.MiscExternalExpensesNondeductibleAccountName(), '8660'); + ContosoGLAccount.AddAccountForLocalization(ExpenseGLAccount.RentalVehiclesAccountName(), '8435'); + end; + + var + ContosoGLAccount: Codeunit "Contoso GL Account"; + ExpenseGLAccount: Codeunit "Create Expense G/L Account"; +} diff --git a/src/Apps/W1/ExpenseAgent/demo data/Country/NZ/NZExpPostingGrp.Codeunit.al b/src/Apps/W1/ExpenseAgent/demo data/Country/NZ/NZExpPostingGrp.Codeunit.al new file mode 100644 index 00000000000..515904a598b --- /dev/null +++ b/src/Apps/W1/ExpenseAgent/demo data/Country/NZ/NZExpPostingGrp.Codeunit.al @@ -0,0 +1,65 @@ +// ------------------------------------------------------------------------------------------------ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. See License.txt in the project root for license information. +// ------------------------------------------------------------------------------------------------ +namespace Microsoft.ExpenseAgent; + +using Microsoft.DemoData.Finance; + +codeunit 8257 "NZ Exp. Posting Grp" +{ + SingleInstance = true; + EventSubscriberInstance = Manual; + InherentEntitlements = X; + InherentPermissions = X; + + trigger OnRun() + var + ContosoExpenseAgent: Codeunit "Contoso Expense Agent"; + begin + ContosoExpenseAgent.InsertExpensePostingGroup(ExpensePerDiem(), ExpensePerDiemLbl); + end; + + [EventSubscriber(ObjectType::Table, Database::"Expense Posting Group", 'OnBeforeInsertEvent', '', false, false)] + local procedure OnInsertRecord(var Rec: Record "Expense Posting Group") + var + CreateGLAccount: Codeunit "Create G/L Account"; + ExpenseGLAccount: Codeunit "Create Expense G/L Account"; + CreateExpensePostingGroup: Codeunit "Create Expense Posting Group"; + begin + case Rec.Code of + CreateExpensePostingGroup.ExpenseEntertainment(): + ValidateRecordFields(Rec, ExpenseGLAccount.FindGLAccountByName(CreateGLAccount.EntertainmentandPRName()), ExpenseGLAccount.FindGLAccountByName(CreateGLAccount.FinanceChargestoVendorsName()), ExpenseGLAccount.EmployeePrepaymentsExpensesAccount(), ExpenseGLAccount.FindGLAccountByName(CreateGLAccount.InvoiceRoundingName()), ExpenseGLAccount.FindGLAccountByName(CreateGLAccount.InvoiceRoundingName())); + CreateExpensePostingGroup.ExpenseMeals(): + ValidateRecordFields(Rec, ExpenseGLAccount.MealExpensesDeductibleAccount(), ExpenseGLAccount.FindGLAccountByName(CreateGLAccount.FinanceChargestoVendorsName()), ExpenseGLAccount.EmployeePrepaymentsExpensesAccount(), ExpenseGLAccount.FindGLAccountByName(CreateGLAccount.InvoiceRoundingName()), ExpenseGLAccount.FindGLAccountByName(CreateGLAccount.InvoiceRoundingName())); + CreateExpensePostingGroup.ExpenseMileage(): + ValidateRecordFields(Rec, ExpenseGLAccount.MileageTravelExpensesAccount(), '', ExpenseGLAccount.EmployeePrepaymentsExpensesAccount(), ExpenseGLAccount.FindGLAccountByName(CreateGLAccount.InvoiceRoundingName()), ExpenseGLAccount.FindGLAccountByName(CreateGLAccount.InvoiceRoundingName())); + CreateExpensePostingGroup.ExpenseOther(): + ValidateRecordFields(Rec, ExpenseGLAccount.MiscExternalExpensesNondeductibleAccount(), ExpenseGLAccount.FindGLAccountByName(CreateGLAccount.FinanceChargestoVendorsName()), ExpenseGLAccount.EmployeePrepaymentsExpensesAccount(), ExpenseGLAccount.FindGLAccountByName(CreateGLAccount.InvoiceRoundingName()), ExpenseGLAccount.FindGLAccountByName(CreateGLAccount.InvoiceRoundingName())); + ExpensePerDiem(): + ValidateRecordFields(Rec, ExpenseGLAccount.PerDiemTravelExpensesAccount(), '', ExpenseGLAccount.EmployeePrepaymentsExpensesAccount(), ExpenseGLAccount.FindGLAccountByName(CreateGLAccount.InvoiceRoundingName()), ExpenseGLAccount.FindGLAccountByName(CreateGLAccount.InvoiceRoundingName())); + CreateExpensePostingGroup.ExpenseTravel(): + ValidateRecordFields(Rec, ExpenseGLAccount.FindGLAccountByName(CreateGLAccount.TravelName()), ExpenseGLAccount.FindGLAccountByName(CreateGLAccount.FinanceChargestoVendorsName()), ExpenseGLAccount.EmployeePrepaymentsExpensesAccount(), ExpenseGLAccount.FindGLAccountByName(CreateGLAccount.InvoiceRoundingName()), ExpenseGLAccount.FindGLAccountByName(CreateGLAccount.InvoiceRoundingName())); + CreateExpensePostingGroup.ExpenseRentalCars(): + ValidateRecordFields(Rec, ExpenseGLAccount.RentalVehiclesAccount(), ExpenseGLAccount.FindGLAccountByName(CreateGLAccount.FinanceChargestoVendorsName()), ExpenseGLAccount.EmployeePrepaymentsExpensesAccount(), ExpenseGLAccount.FindGLAccountByName(CreateGLAccount.InvoiceRoundingName()), ExpenseGLAccount.FindGLAccountByName(CreateGLAccount.InvoiceRoundingName())); + end; + end; + + local procedure ValidateRecordFields(var ExpensePostingGroup: Record "Expense Posting Group"; RefundableDebitAccount: Code[20]; NonRefundableDebitAccount: Code[20]; PrepaymentCreditAccount: Code[20]; ExpenseDebitRoundingAccount: Code[20]; ExpenseCreditRoundingAccount: Code[20]) + begin + ExpensePostingGroup.Validate("Refundable Debit Account", RefundableDebitAccount); + ExpensePostingGroup.Validate("Non-Refundable Debit Account", NonRefundableDebitAccount); + ExpensePostingGroup.Validate("Prepayment Credit Account", PrepaymentCreditAccount); + ExpensePostingGroup.Validate("Debit Rounding Account", ExpenseDebitRoundingAccount); + ExpensePostingGroup.Validate("Credit Rounding Account", ExpenseCreditRoundingAccount); + end; + + var + ExpensePERDIEMTok: Label 'EXPENSE-PERDIEM', MaxLength = 20, Locked = true; + ExpensePerDiemLbl: Label 'Expense - Per Diem', MaxLength = 100; + + procedure ExpensePerDiem(): Code[20] + begin + exit(ExpensePERDIEMTok); + end; +} diff --git a/src/Apps/W1/ExpenseAgent/demo data/Country/NZ/NZExpRuleCondition.Codeunit.al b/src/Apps/W1/ExpenseAgent/demo data/Country/NZ/NZExpRuleCondition.Codeunit.al new file mode 100644 index 00000000000..7ad4573bc47 --- /dev/null +++ b/src/Apps/W1/ExpenseAgent/demo data/Country/NZ/NZExpRuleCondition.Codeunit.al @@ -0,0 +1,26 @@ +// ------------------------------------------------------------------------------------------------ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. See License.txt in the project root for license information. +// ------------------------------------------------------------------------------------------------ +namespace Microsoft.ExpenseAgent; + +codeunit 8262 "NZ Exp. Rule Condition" +{ + InherentEntitlements = X; + InherentPermissions = X; + + trigger OnRun() + var + NZExpCategories: Codeunit "NZ Exp. Categories"; + CreateExpenseLocation: Codeunit "Create Expense Location"; + ContosoExpenseAgent: Codeunit "Contoso Expense Agent"; + begin + ContosoExpenseAgent.InsertExpenseRuleCondition(NZExpCategories.PerDiem(), CreateExpenseLocation.CanadaAll(), 0D, 10000, Enum::"Expense Rule Condition Type"::"Daily Rate", 125); + ContosoExpenseAgent.InsertExpenseRuleCondition(NZExpCategories.PerDiem(), CreateExpenseLocation.DenmarkAll(), 0D, 10000, Enum::"Expense Rule Condition Type"::"Daily Rate", 450); + ContosoExpenseAgent.InsertExpenseRuleCondition(NZExpCategories.PerDiem(), CreateExpenseLocation.Domestic(), 0D, 10000, Enum::"Expense Rule Condition Type"::"Daily Rate", 50); + ContosoExpenseAgent.InsertExpenseRuleCondition(NZExpCategories.PerDiem(), CreateExpenseLocation.FranceAll(), 0D, 10000, Enum::"Expense Rule Condition Type"::"Daily Rate", 110); + ContosoExpenseAgent.InsertExpenseRuleCondition(NZExpCategories.PerDiem(), CreateExpenseLocation.GermanyAll(), 0D, 10000, Enum::"Expense Rule Condition Type"::"Daily Rate", 105); + ContosoExpenseAgent.InsertExpenseRuleCondition(NZExpCategories.PerDiem(), CreateExpenseLocation.UKOther(), 0D, 10000, Enum::"Expense Rule Condition Type"::"Daily Rate", 115); + ContosoExpenseAgent.InsertExpenseRuleCondition(NZExpCategories.PerDiem(), CreateExpenseLocation.USAOther(), 0D, 10000, Enum::"Expense Rule Condition Type"::"Daily Rate", 120); + end; +} diff --git a/src/Apps/W1/ExpenseAgent/demo data/Country/NZ/NZExpRuleHeader.Codeunit.al b/src/Apps/W1/ExpenseAgent/demo data/Country/NZ/NZExpRuleHeader.Codeunit.al new file mode 100644 index 00000000000..d683da5442e --- /dev/null +++ b/src/Apps/W1/ExpenseAgent/demo data/Country/NZ/NZExpRuleHeader.Codeunit.al @@ -0,0 +1,29 @@ +// ------------------------------------------------------------------------------------------------ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. See License.txt in the project root for license information. +// ------------------------------------------------------------------------------------------------ +namespace Microsoft.ExpenseAgent; + +using Microsoft.DemoData.Finance; + +codeunit 8261 "NZ Exp. Rule Header" +{ + InherentEntitlements = X; + InherentPermissions = X; + + trigger OnRun() + var + CreateCurrency: Codeunit "Create Currency"; + NZExpCategories: Codeunit "NZ Exp. Categories"; + CreateExpenseLocation: Codeunit "Create Expense Location"; + ContosoExpenseAgent: Codeunit "Contoso Expense Agent"; + begin + ContosoExpenseAgent.InsertExpenseRuleHeader(NZExpCategories.PerDiem(), CreateExpenseLocation.CanadaAll(), 0D, Enum::"Expense Justification"::" ", false, '', CreateCurrency.CAD(), ''); + ContosoExpenseAgent.InsertExpenseRuleHeader(NZExpCategories.PerDiem(), CreateExpenseLocation.DenmarkAll(), 0D, Enum::"Expense Justification"::" ", false, '', CreateCurrency.EUR(), ''); + ContosoExpenseAgent.InsertExpenseRuleHeader(NZExpCategories.PerDiem(), CreateExpenseLocation.Domestic(), 0D, Enum::"Expense Justification"::" ", false, '', '', ''); + ContosoExpenseAgent.InsertExpenseRuleHeader(NZExpCategories.PerDiem(), CreateExpenseLocation.FranceAll(), 0D, Enum::"Expense Justification"::" ", false, '', CreateCurrency.EUR(), ''); + ContosoExpenseAgent.InsertExpenseRuleHeader(NZExpCategories.PerDiem(), CreateExpenseLocation.GermanyAll(), 0D, Enum::"Expense Justification"::" ", false, '', CreateCurrency.EUR(), ''); + ContosoExpenseAgent.InsertExpenseRuleHeader(NZExpCategories.PerDiem(), CreateExpenseLocation.UKOther(), 0D, Enum::"Expense Justification"::" ", false, '', CreateCurrency.GBP(), ''); + ContosoExpenseAgent.InsertExpenseRuleHeader(NZExpCategories.PerDiem(), CreateExpenseLocation.USAOther(), 0D, Enum::"Expense Justification"::" ", false, '', '', ''); + end; +} diff --git a/src/Apps/W1/ExpenseAgent/demo data/Country/NZ/NZExpSubCategories.Codeunit.al b/src/Apps/W1/ExpenseAgent/demo data/Country/NZ/NZExpSubCategories.Codeunit.al new file mode 100644 index 00000000000..110d963af00 --- /dev/null +++ b/src/Apps/W1/ExpenseAgent/demo data/Country/NZ/NZExpSubCategories.Codeunit.al @@ -0,0 +1,39 @@ +// ------------------------------------------------------------------------------------------------ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. See License.txt in the project root for license information. +// ------------------------------------------------------------------------------------------------ +namespace Microsoft.ExpenseAgent; + +codeunit 8260 "NZ Exp. SubCategories" +{ + InherentEntitlements = X; + InherentPermissions = X; + + trigger OnRun() + var + ContosoExpenseAgent: Codeunit "Contoso Expense Agent"; + NZExpCategories: Codeunit "NZ Exp. Categories"; + begin + // PER-DIEM subcategories + ContosoExpenseAgent.InsertExpenseSubcategory(Country(), NZExpCategories.PerDiem(), LocalCountryPerDiemLbl, LocalCountryPerDiemPostingLbl, false, true, false); + ContosoExpenseAgent.InsertExpenseSubcategory(Intl(), NZExpCategories.PerDiem(), InternationalPerDiemLbl, InternationalPerDiemPostingLbl, false, true, false); + end; + + var + CountryTok: Label 'COUNTRY', MaxLength = 20, Locked = true; + IntlTok: Label 'INTL', MaxLength = 20, Locked = true; + LocalCountryPerDiemLbl: Label 'Daily per-diem allowance based on domestic travel rates, paid instead of individual meal or incidental expense reimbursements.', MaxLength = 250; + InternationalPerDiemLbl: Label 'Daily per-diem allowance for international business travel, based on applicable foreign travel rates.', MaxLength = 250; + LocalCountryPerDiemPostingLbl: Label 'Local country per-diem', MaxLength = 100; + InternationalPerDiemPostingLbl: Label 'International per-diem', MaxLength = 100; + + procedure Country(): Code[20] + begin + exit(CountryTok); + end; + + procedure Intl(): Code[20] + begin + exit(IntlTok); + end; +} diff --git a/src/Apps/W1/ExpenseAgent/demo data/Country/NZ/NZExpense.Codeunit.al b/src/Apps/W1/ExpenseAgent/demo data/Country/NZ/NZExpense.Codeunit.al new file mode 100644 index 00000000000..adec4da6464 --- /dev/null +++ b/src/Apps/W1/ExpenseAgent/demo data/Country/NZ/NZExpense.Codeunit.al @@ -0,0 +1,51 @@ +// ------------------------------------------------------------------------------------------------ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. See License.txt in the project root for license information. +// ------------------------------------------------------------------------------------------------ +namespace Microsoft.ExpenseAgent; + +using Microsoft.DemoTool.Helpers; + +codeunit 8263 "NZ Expense" +{ + InherentEntitlements = X; + InherentPermissions = X; + Permissions = tabledata "Expense Per Diem" = rim; + + trigger OnRun() + begin + CreateOpenExpense(); + end; + + local procedure CreateOpenExpense() + var + Expense: Record Expense; + ContosoExpenseAgent: Codeunit "Contoso Expense Agent"; + CreateExpenseLocation: Codeunit "Create Expense Location"; + begin + Expense := ContosoExpenseAgent.InsertExpense(CreateExpenseUser.EH(), NZExpCategories.PerDiem(), CreateExpenseLocation.DenmarkAll(), PerDiemByAssignedPolicyLbl, '', ContosoUtility.AdjustDate(19030203D), '', 0, '', CreateExpensePaymentMethod.Cash(), true, false, '', CreateDateTime(ContosoUtility.AdjustDate(19030115D), 144000T), CreateDateTime(ContosoUtility.AdjustDate(19030121D), 000500T), 0, 0, '', '', '', '', ''); + UpdateExpensePerDiem(Expense."No.", 10000, false, false, true); + UpdateExpensePerDiem(Expense."No.", 30000, false, true, false); + UpdateExpensePerDiem(Expense."No.", 40000, false, false, true); + UpdateExpensePerDiem(Expense."No.", 60000, false, true, true); + end; + + var + ContosoUtility: Codeunit "Contoso Utilities"; + CreateExpenseUser: Codeunit "Create Expense User"; + NZExpCategories: Codeunit "NZ Exp. Categories"; + CreateExpensePaymentMethod: Codeunit "Create Expense Payment Method"; + PerDiemByAssignedPolicyLbl: Label 'Per-diem by assigned policy', MaxLength = 100; + + local procedure UpdateExpensePerDiem(ExpenseNo: Code[20]; LineNo: Integer; Breakfast: Boolean; Lunch: Boolean; Dinner: Boolean) + var + ExpensePerDiem: Record "Expense Per Diem"; + begin + ExpensePerDiem.Get(ExpenseNo, LineNo); + + ExpensePerDiem.Validate(Breakfast, Breakfast); + ExpensePerDiem.Validate(Lunch, Lunch); + ExpensePerDiem.Validate(Dinner, Dinner); + ExpensePerDiem.Modify(); + end; +} diff --git a/src/Apps/W1/ExpenseAgent/demo data/Country/NZ/NZPostedExpReport.Codeunit.al b/src/Apps/W1/ExpenseAgent/demo data/Country/NZ/NZPostedExpReport.Codeunit.al new file mode 100644 index 00000000000..661e36af095 --- /dev/null +++ b/src/Apps/W1/ExpenseAgent/demo data/Country/NZ/NZPostedExpReport.Codeunit.al @@ -0,0 +1,168 @@ +// ------------------------------------------------------------------------------------------------ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. See License.txt in the project root for license information. +// ------------------------------------------------------------------------------------------------ +namespace Microsoft.ExpenseAgent; + +using Microsoft.DemoData.Finance; +using Microsoft.DemoData.HumanResources; +using Microsoft.DemoTool.Helpers; + +codeunit 8264 "NZ Posted Exp. Report" +{ + SingleInstance = true; + EventSubscriberInstance = Manual; + InherentEntitlements = X; + InherentPermissions = X; + Permissions = + tabledata "Expense Per Diem" = rim, + tabledata "Expense Report Line" = rim; + + trigger OnRun() + var + ExpenseReportHeader: Record "Expense Report Header"; + begin + if ExpenseReportHeader.FindLast() then + FromExpenseReportNo := ExpenseReportHeader."No."; + + CreateExpenseReportToPost(); + + PostExpenseReport(); + end; + + [EventSubscriber(ObjectType::Codeunit, Codeunit::"Create Posted Expense Report", OnDefineExpenseAccountNo, '', false, false)] + local procedure OnDefineExpenseAccountNo(var AccountNo: Code[20]) + var + CreateGLAccount: Codeunit "Create G/L Account"; + ExpenseGLAccount: Codeunit "Create Expense G/L Account"; + begin + AccountNo := ExpenseGLAccount.FindGLAccountByName(CreateGLAccount.SalesResourcesExportName()); + end; + + local procedure CreateExpenseReportToPost() + var + Expense: Record Expense; + ExpenseReportHeader: Record "Expense Report Header"; + CreateEmployee: Codeunit "Create Employee"; + CreateCurrency: Codeunit "Create Currency"; + ContosoUtility: Codeunit "Contoso Utilities"; + CreateExpenseUser: Codeunit "Create Expense User"; + CreateExpenseLocation: Codeunit "Create Expense Location"; + ContosoExpenseAgent: Codeunit "Contoso Expense Agent"; + CreateExpCategories: Codeunit "Create Expense Categories DM"; + NZExpCategories: Codeunit "NZ Exp. Categories"; + CreateExpenseSubcategories: Codeunit "Create Expense Subcategories"; + CreateExpensePaymentMethod: Codeunit "Create Expense Payment Method"; + begin + ExpenseReportHeader := ContosoExpenseAgent.InsertExpenseReportHeader(CreateExpenseUser.JO(), ContosoUtility.AdjustDate(19021104D), ContosoUtility.AdjustDate(19021104D)); + Expense := ContosoExpenseAgent.InsertExpense(CreateExpenseUser.JO(), NZExpCategories.PerDiem(), CreateExpenseLocation.GermanyAll(), BusinessTripToHamburgLbl, '', ContosoUtility.AdjustDate(19021103D), '', 0, '', CreateExpensePaymentMethod.Cash(), true, false, '', CreateDateTime(ContosoUtility.AdjustDate(19021024D), 064500T), CreateDateTime(ContosoUtility.AdjustDate(19021027D), 161500T), 0, 0, '', '', '', '', ''); + ReleaseAndAddExpenseToExpenseReport(Expense, ExpenseReportHeader); + Expense := ContosoExpenseAgent.InsertExpense(CreateExpenseUser.JO(), CreateExpCategories.Airline(), '', AirlineTicketsLbl, '', ContosoUtility.AdjustDate(19021010D), '', 2042, MargieTravelLbl, CreateExpensePaymentMethod.Card(), true, false, '', 0DT, 0DT, 0, 0, '', '', 'TY6HJO', '', ''); + ReleaseAndAddExpenseToExpenseReport(Expense, ExpenseReportHeader); + + ExpenseReportHeader := ContosoExpenseAgent.InsertExpenseReportHeader(CreateExpenseUser.EH(), ContosoUtility.AdjustDate(19021204D), ContosoUtility.AdjustDate(19021204D)); + Expense := ContosoExpenseAgent.InsertExpense(CreateExpenseUser.EH(), CreateExpCategories.Airline(), '', AirlineTicketsDublinLbl, TravelToConferenceLbl, ContosoUtility.AdjustDate(19021106D), '', 3120, MargieTravelLbl, CreateExpensePaymentMethod.Card(), true, false, '', 0DT, 0DT, 0, 0, '', '', 'FIUXHJT', '', ''); + ReleaseAndAddExpenseToExpenseReport(Expense, ExpenseReportHeader); + Expense := ContosoExpenseAgent.InsertExpense(CreateExpenseUser.EH(), CreateExpCategories.Events(), '', ITConferenceLbl, '', ContosoUtility.AdjustDate(19021107D), CreateCurrency.EUR(), 1990, ProsewareIncLbl, CreateExpensePaymentMethod.Card(), true, false, '', 0DT, 0DT, 0, 0, '', '', 'G574576HJ656', '', ''); + ReleaseAndAddExpenseToExpenseReport(Expense, ExpenseReportHeader); + Expense := ContosoExpenseAgent.InsertExpense(CreateExpenseUser.EH(), CreateExpCategories.GroundTransportation(), '', TaxiLbl, '', ContosoUtility.AdjustDate(19021114D), CreateCurrency.EUR(), 45, TailwindTradersLbl, CreateExpensePaymentMethod.Cash(), true, false, '', 0DT, 0DT, 0, 0, '', '', '456845856867', '', ''); + ReleaseAndAddExpenseToExpenseReport(Expense, ExpenseReportHeader); + Expense := ContosoExpenseAgent.InsertExpense(CreateExpenseUser.EH(), CreateExpCategories.Entertain(), '', BusinessDinnerLbl, BusinessDinnerWithBigPotentialCustomersLbl, ContosoUtility.AdjustDate(19021116D), CreateCurrency.EUR(), 842, FourthCoffeeLbl, CreateExpensePaymentMethod.Card(), true, false, '', 0DT, 0DT, 0, 0, '', '', 'RT6457560034', '', ''); + ContosoExpenseAgent.InsertExpenseParticipant(Expense."No.", 10000, CreateExpCategories.Entertain(), Enum::"Expense Participant Type"::Employee, CreateEmployee.ManagingDirector(), '', '', '', '', ''); + ContosoExpenseAgent.InsertExpenseParticipant(Expense."No.", 20000, CreateExpCategories.Entertain(), Enum::"Expense Participant Type"::Employee, CreateEmployee.SalesManager(), '', '', '', '', ''); + ContosoExpenseAgent.InsertExpenseParticipant(Expense."No.", 30000, CreateExpCategories.Entertain(), Enum::"Expense Participant Type"::External, '', JesseHomerLbl, RelecloudLbl, '', CEOLbl, 'jesse.homer@contoso.com'); + ContosoExpenseAgent.InsertExpenseParticipant(Expense."No.", 40000, CreateExpCategories.Entertain(), Enum::"Expense Participant Type"::External, '', RobertTownesLbl, AdatumCorporationLbl, '', CEOLbl, 'robert.townes@contoso.com'); + ReleaseAndAddExpenseToExpenseReport(Expense, ExpenseReportHeader); + Expense := ContosoExpenseAgent.InsertExpense(CreateExpenseUser.EH(), CreateExpCategories.Hotels(), '', HotelStayLbl, '', ContosoUtility.AdjustDate(19021118D), CreateCurrency.EUR(), 2150, ContosoSuitesLbl, CreateExpensePaymentMethod.Card(), true, false, '', 0DT, 0DT, 0, 0, '', '', '64675S879CT987990004', '', ''); + ContosoExpenseAgent.InsertExpenseItemization(Expense."No.", 10000, CreateExpCategories.Hotels(), CreateExpenseSubcategories.Room(), AccommodationLbl, ContosoUtility.AdjustDate(19021114D), 390); + ContosoExpenseAgent.InsertExpenseItemization(Expense."No.", 20000, CreateExpCategories.Hotels(), CreateExpenseSubcategories.Breakfast(), BreakfastLbl, ContosoUtility.AdjustDate(19021115D), 35); + ContosoExpenseAgent.InsertExpenseItemization(Expense."No.", 30000, CreateExpCategories.Hotels(), CreateExpenseSubcategories.Room(), AccommodationLbl, ContosoUtility.AdjustDate(19021115D), 390); + ContosoExpenseAgent.InsertExpenseItemization(Expense."No.", 40000, CreateExpCategories.Hotels(), CreateExpenseSubcategories.Breakfast(), BreakfastLbl, ContosoUtility.AdjustDate(19021116D), 35); + ContosoExpenseAgent.InsertExpenseItemization(Expense."No.", 50000, CreateExpCategories.Hotels(), CreateExpenseSubcategories.Room(), AccommodationLbl, ContosoUtility.AdjustDate(19021116D), 390); + ContosoExpenseAgent.InsertExpenseItemization(Expense."No.", 60000, CreateExpCategories.Hotels(), CreateExpenseSubcategories.RoomService(), RoomServiceLbl, ContosoUtility.AdjustDate(19021116D), 145); + ContosoExpenseAgent.InsertExpenseItemization(Expense."No.", 70000, CreateExpCategories.Hotels(), CreateExpenseSubcategories.Breakfast(), BreakfastLbl, ContosoUtility.AdjustDate(19021117D), 35); + ContosoExpenseAgent.InsertExpenseItemization(Expense."No.", 80000, CreateExpCategories.Hotels(), CreateExpenseSubcategories.Room(), AccommodationLbl, ContosoUtility.AdjustDate(19021117D), 390); + ContosoExpenseAgent.InsertExpenseItemization(Expense."No.", 90000, CreateExpCategories.Hotels(), CreateExpenseSubcategories.Breakfast(), BreakfastLbl, ContosoUtility.AdjustDate(19021118D), 35); + ContosoExpenseAgent.InsertExpenseItemization(Expense."No.", 100000, CreateExpCategories.Hotels(), CreateExpenseSubcategories.Tax(), HotelTaxesLbl, ContosoUtility.AdjustDate(19021118D), 305); + ReleaseAndAddExpenseToExpenseReport(Expense, ExpenseReportHeader); + Expense := ContosoExpenseAgent.InsertExpense(CreateExpenseUser.EH(), CreateExpCategories.RentalCars(), '', CarRentalsLbl, '', ContosoUtility.AdjustDate(19021118D), CreateCurrency.EUR(), 622.45, VanArsdelLtdLbl, CreateExpensePaymentMethod.Card(), true, false, '', 0DT, 0DT, 0, 0, '', '', 'H6584769867J9J95789', '', ''); + ReleaseAndAddExpenseToExpenseReport(Expense, ExpenseReportHeader); + Expense := ContosoExpenseAgent.InsertExpense(CreateExpenseUser.EH(), CreateExpCategories.GroundTransportation(), '', TaxiLbl, '', ContosoUtility.AdjustDate(19021118D), CreateCurrency.EUR(), 71, TailwindTradersLbl, CreateExpensePaymentMethod.Cash(), true, false, '', 0DT, 0DT, 0, 0, '', '', '7456875687568', '', ''); + ReleaseAndAddExpenseToExpenseReport(Expense, ExpenseReportHeader); + Expense := ContosoExpenseAgent.InsertExpense(CreateExpenseUser.EH(), NZExpCategories.PerDiem(), CreateExpenseLocation.UKOther(), TripToUKLbl, '', ContosoUtility.AdjustDate(19021121D), '', 0, '', CreateExpensePaymentMethod.Cash(), true, false, '', CreateDateTime(ContosoUtility.AdjustDate(19021114D), 053000T), CreateDateTime(ContosoUtility.AdjustDate(19021118D), 220500T), 0, 0, '', '', '', '', ''); + UpdateExpensePerDiem(Expense."No.", 20000, false, false, true); + UpdateExpensePerDiem(Expense."No.", 40000, false, true, false); + ReleaseAndAddExpenseToExpenseReport(Expense, ExpenseReportHeader); + Expense := ContosoExpenseAgent.InsertExpense(CreateExpenseUser.EH(), NZExpCategories.PerDiem(), CreateExpenseLocation.Domestic(), TripToDoverLbl, '', ContosoUtility.AdjustDate(19021204D), '', 0, '', CreateExpensePaymentMethod.Cash(), true, false, '', CreateDateTime(ContosoUtility.AdjustDate(19021127D), 070000T), CreateDateTime(ContosoUtility.AdjustDate(19021129D), 145500T), 0, 0, '', '', '', '', ''); + ReleaseAndAddExpenseToExpenseReport(Expense, ExpenseReportHeader); + Expense := ContosoExpenseAgent.InsertExpense(CreateExpenseUser.EH(), CreateExpCategories.Mileage(), '', MileageLbl, '', ContosoUtility.AdjustDate(19031101D), '', 0, VanArsdelLtdLbl, CreateExpensePaymentMethod.Cash(), true, false, '', 0DT, 0DT, 0, 249, 'New York', 'Dover', 'H6584769867J9J95789', '', ''); + ReleaseAndAddExpenseToExpenseReport(Expense, ExpenseReportHeader); + end; + + var + FromExpenseReportNo: Code[20]; + BusinessTripToHamburgLbl: Label 'Business trip to Hamburg, DE', MaxLength = 100; + AirlineTicketsLbl: Label 'Airline tickets NY/FRANKFURT/HAMBURG/FRANKFURT/NY', MaxLength = 100; + MargieTravelLbl: Label 'Margie''s Travel', MaxLength = 100; + AirlineTicketsDublinLbl: Label 'Airline tickets NY/DUBLIN/NY', MaxLength = 100; + TravelToConferenceLbl: Label 'Travel to the conference', MaxLength = 100; + ITConferenceLbl: Label 'IT Conference', MaxLength = 100; + ProsewareIncLbl: Label 'Proseware, Inc.', MaxLength = 100; + TaxiLbl: Label 'Taxi', MaxLength = 100; + TailwindTradersLbl: Label 'Tailwind Traders', MaxLength = 100; + BusinessDinnerLbl: Label 'Business Dinner', MaxLength = 100; + BusinessDinnerWithBigPotentialCustomersLbl: Label 'Business dinner with a big potential customers', MaxLength = 100; + FourthCoffeeLbl: Label 'Fourth Coffee', MaxLength = 100; + JesseHomerLbl: Label 'Jesse Homer', MaxLength = 100; + RelecloudLbl: Label 'Relecloud', MaxLength = 100; + RobertTownesLbl: Label 'Robert Townes', MaxLength = 100; + AdatumCorporationLbl: Label 'Adatum Corporation', MaxLength = 100; + HotelStayLbl: Label 'Hotel stay', MaxLength = 100; + ContosoSuitesLbl: Label 'Contoso Suites', MaxLength = 100; + AccommodationLbl: Label 'Accommodation', MaxLength = 100; + BreakfastLbl: Label 'Breakfast', MaxLength = 100; + HotelTaxesLbl: Label 'Hotel Taxes', MaxLength = 100; + RoomServiceLbl: Label 'Room service', MaxLength = 100; + CarRentalsLbl: Label 'Car Rentals', MaxLength = 100; + VanArsdelLtdLbl: Label 'VanArsdel, Ltd.', MaxLength = 100; + TripToUKLbl: Label 'Trip to UK', MaxLength = 100; + TripToDoverLbl: Label 'Trip to Dover', MaxLength = 100; + MileageLbl: Label 'Mileage', MaxLength = 100; + CEOLbl: Label 'CEO', MaxLength = 30; + + local procedure ReleaseAndAddExpenseToExpenseReport(Expense: Record Expense; ExpenseReportHeader: Record "Expense Report Header") + var + ReleaseExpenseDocument: Codeunit "Release Expense Document"; + CreateExpenseReport: Codeunit "Create Expense Report"; + begin + Expense.Get(Expense."No."); + ReleaseExpenseDocument.Run(Expense); + + CreateExpenseReport.AddSingleExpenseToExpenseReport(Expense, ExpenseReportHeader); + end; + + local procedure PostExpenseReport() + var + ExpenseReportHeader: Record "Expense Report Header"; + begin + if FromExpenseReportNo <> '' then + ExpenseReportHeader.SetFilter("No.", '>%1', FromExpenseReportNo); + + if ExpenseReportHeader.FindSet() then + repeat + Codeunit.Run(Codeunit::"Expense Report-Post", ExpenseReportHeader); + until ExpenseReportHeader.Next() = 0; + end; + + local procedure UpdateExpensePerDiem(ExpenseNo: Code[20]; LineNo: Integer; Breakfast: Boolean; Lunch: Boolean; Dinner: Boolean) + var + ExpensePerDiem: Record "Expense Per Diem"; + begin + ExpensePerDiem.Get(ExpenseNo, LineNo); + + ExpensePerDiem.Validate(Breakfast, Breakfast); + ExpensePerDiem.Validate(Lunch, Lunch); + ExpensePerDiem.Validate(Dinner, Dinner); + ExpensePerDiem.Modify(); + end; +} diff --git a/src/Apps/W1/ExpenseAgent/demo data/Country/NZ/NZUpdEmpPostingGrp.Codeunit.al b/src/Apps/W1/ExpenseAgent/demo data/Country/NZ/NZUpdEmpPostingGrp.Codeunit.al new file mode 100644 index 00000000000..36b465160c5 --- /dev/null +++ b/src/Apps/W1/ExpenseAgent/demo data/Country/NZ/NZUpdEmpPostingGrp.Codeunit.al @@ -0,0 +1,31 @@ +// ------------------------------------------------------------------------------------------------ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. See License.txt in the project root for license information. +// ------------------------------------------------------------------------------------------------ +namespace Microsoft.ExpenseAgent; + +using Microsoft.DemoData.Finance; +using Microsoft.DemoData.HumanResources; + +codeunit 8258 "NZ Upd. Emp. Posting Grp" +{ + InherentEntitlements = X; + InherentPermissions = X; + + trigger OnRun() + begin + UpdateEmployeePostingGroup(); + end; + + local procedure UpdateEmployeePostingGroup() + var + CreateGLAccount: Codeunit "Create G/L Account"; + ExpenseGLAccount: Codeunit "Create Expense G/L Account"; + ContosoExpenseAgent: Codeunit "Contoso Expense Agent"; + CreateEmployeePostingGroup: Codeunit "Create Employee Posting Group"; + begin + ContosoExpenseAgent.SetOverwriteData(true); + ContosoExpenseAgent.UpdateEmployeePostingGroup(CreateEmployeePostingGroup.EmployeeExpenses(), ExpenseGLAccount.FindGLAccountByName(CreateGLAccount.EmployeesPayableName()), ExpenseGLAccount.EmployeePrepaymentsExpensesAccount(), ExpenseGLAccount.FindGLAccountByName(CreateGLAccount.BankLCYName()), ExpenseGLAccount.CompanyCreditCardsAccount()); + ContosoExpenseAgent.SetOverwriteData(false); + end; +} diff --git a/src/Apps/W1/ExpenseAgent/demo data/Country/PORTING_NOTES.md b/src/Apps/W1/ExpenseAgent/demo data/Country/PORTING_NOTES.md new file mode 100644 index 00000000000..f7a97b6594e --- /dev/null +++ b/src/Apps/W1/ExpenseAgent/demo data/Country/PORTING_NOTES.md @@ -0,0 +1,280 @@ +# Expense Agent — Country Demo Data Consolidation Notes + +This file catalogs the technical workarounds applied while porting the ten +per-country Expense Agent demo-data extensions into the consolidated +`Expense Agent Demo Data` (W1) extension. + +## Rationale + +The consolidated demo data extension must be installable on **any** BC +localization — it can only depend on: + +- `Expense Agent (Preview)` (base app) +- `Contoso Coffee Demo Dataset` (base W1 Contoso Coffee) +- `Expense Agent Demo Data` (itself, framework layer) + +It cannot add hard dependencies on `Contoso Coffee Demo Dataset ()` or on +any country localization pack (which would restrict installability to that +country only). + +The original per-country apps (`ExpenseAgent_/demo data`) freely referenced +`Create GL Accounts` codeunits from `Contoso Coffee Demo Dataset ()` +and, in the ES case, the `Income Stmt. Bal. Acc.` field added by the ES +localization. Neither is available here. + +**All data written on the target locale (numbers, names, categories, +income/balance flags, posting types, etc.) is byte-identical to the original +per-country app output.** The workarounds change *how* a value is looked up, +not *what* value is written. + +## Data preservation + +For every country, the following are copied verbatim from the original +`CreateExpenseGLAccount.Codeunit.al` / `ExpenseEventSubscriber.Codeunit.al`: + +- G/L account numbers (`AddAccountForLocalization(name, number)`) +- G/L account names (`Label` values) +- Income/Balance flag +- G/L Account Category + SubCategory +- Account Type (Posting / Begin-Total / End-Total) +- Begin-Total / End-Total Totaling ranges (CA, NZ) +- General Posting Type +- Direct Posting / Reconciliation / Blocked flags +- Expense Posting Group account mappings (Refundable/Non-refundable/Prepayment/Rounding) +- Employee Posting Group mappings +- Categories / SubCategories / Rule Header / Rule Condition / Expense / + Posted Expense Report data (labels, dates, amounts, vendors, participants) + +--- + +## Judgment calls (per country) + +### Pattern A — Inlined `Contoso Coffee (CC)` name-lookup labels + +**Problem:** original per-country apps look up G/L accounts by name using +`Create GL Account.()` from `Contoso Coffee Demo Dataset ()`. +The consolidated extension cannot depend on the country ContosoCoffee. + +**Workaround:** create a per-country ` GL Account Names` codeunit that +duplicates the `Tok`/`Lbl` string constants verbatim. The base W1 +`Create Expense G/L Account.FindGLAccountByName(...)` resolves the account by +name at runtime, so on a ``-loc install where the ContosoCoffee-`` pack +is installed, the returned account is identical to the original code path. + +**Alternative rejected:** adding `Contoso Coffee Demo Dataset ()` as a +dependency of the consolidated extension → would make the extension only +installable on `` loc. + +#### US +| # | Label | Value | +|---|-------|-------| +| 1 | `BusinessEntertainingDeductibleName` | `Business Entertaining, deductible` | +| 2 | `OtherIncidentalRevenueName` | `Other Incidental Revenue` | +| 3 | `OtherPrepaidExpensesAndAccruedIncomeName` | `Other prepaid expenses and accrued income` | +| 4 | `PayableInvoiceRoundingName` | `Payable Invoice Rounding` | +| 5 | `MiscExternalExpensesName` | `Misc. external expenses` | +| 6 | `OtherTravelExpensesName` | `Other travel expenses` | +| 7 | `RentalVehiclesName` | `Rental vehicles` | +| 8 | `AccountsPayableDomesticName` | `Accounts Payable, Domestic` | +| 9 | `OtherBankAccountsName` | `Other bank accounts ` (trailing space) | +| 10 | `SaleofResourcesName` | `Sale of Resources` | + +- **Before (original US):** `Create US GL Account.OtherIncidentalRevenue()` and siblings — from `src/Apps/US/ContosoCoffeeDemoDatasetUS/app/DemoData/Finance/1.Setup Data/CreateUSGLAccount.Codeunit.al`. +- **After (ported):** [demo data/Country/US/USGLAccountNames.Codeunit.al](demo%20data/Country/US/USGLAccountNames.Codeunit.al) — codeunit 8220. +- **Used by:** [demo data/Country/US/USExpGLAccount.Codeunit.al](demo%20data/Country/US/USExpGLAccount.Codeunit.al), [demo data/Country/US/USExpPostingGrp.Codeunit.al](demo%20data/Country/US/USExpPostingGrp.Codeunit.al), [demo data/Country/US/USUpdEmpPostingGrp.Codeunit.al](demo%20data/Country/US/USUpdEmpPostingGrp.Codeunit.al), [demo data/Country/US/USPostedExpReport.Codeunit.al](demo%20data/Country/US/USPostedExpReport.Codeunit.al). + +#### GB +| # | Label | Value | +|---|-------|-------| +| 1 | `BusinessEntertainingDeductibleName` | `Business Entertaining, deductible` | +| 2 | `OtherIncidentalRevenueName` | `Other Incidental Revenue` | +| 3 | `OtherPrepaidExpensesAndAccruedIncomeName` | `Other prepaid expenses and accrued income` | +| 4 | `PayableInvoiceRoundingName` | `Payable Invoice Rounding` | +| 5 | `MiscExternalExpensesName` | `Misc. external expenses` | +| 6 | `OtherTravelExpensesName` | `Other travel expenses` | +| 7 | `RentalVehiclesName` | `Rental vehicles` | +| 8 | `OtherBankAccountsName` | `Other bank accounts ` (trailing space) | +| 9 | `SaleofResourcesName` | `Sale of Resources` | + +- **Before (original GB):** `Create UK GL Account.()` from `src/Apps/GB/ContosoCoffeeDemoDatasetGB/app/DemoData/Finance/1.Setup Data/CreateUKGLAccount.Codeunit.al` (or equivalent). +- **After (ported):** [demo data/Country/GB/GBGLAccountNames.Codeunit.al](demo%20data/Country/GB/GBGLAccountNames.Codeunit.al) — codeunit 8235. +- **Used by:** [demo data/Country/GB/GBExpGLAccount.Codeunit.al](demo%20data/Country/GB/GBExpGLAccount.Codeunit.al), [demo data/Country/GB/GBExpPostingGrp.Codeunit.al](demo%20data/Country/GB/GBExpPostingGrp.Codeunit.al), [demo data/Country/GB/GBPostedExpReport.Codeunit.al](demo%20data/Country/GB/GBPostedExpReport.Codeunit.al). + +#### CA +Single label inlined directly in [demo data/Country/CA/CAUpdEmpPostingGrp.Codeunit.al#L33](demo%20data/Country/CA/CAUpdEmpPostingGrp.Codeunit.al#L33): + +```al +BankCheckingLbl: Label 'Bank, Checking', MaxLength = 100; +``` + +- **Before (original CA):** `Create CA GL Account.BankCheckingName()` from `src/Apps/CA/ContosoCoffeeDemoDatasetCA/app/DemoData/Finance/1.Setup Data/CreateCAGLAccount.Codeunit.al`. +- **After (ported):** [demo data/Country/CA/CAUpdEmpPostingGrp.Codeunit.al#L28](demo%20data/Country/CA/CAUpdEmpPostingGrp.Codeunit.al#L28) uses `ExpenseGLAccount.FindGLAccountByName(BankCheckingLbl)`. + +#### ES +| # | Label | Value | +|---|-------|-------| +| 1 | `OtherBusinessExpensesName` | `Other Business Expenses` | +| 2 | `RemunerationAdvancesName` | `Remuneration Advances` | +| 3 | `BanksEuroName` | `Banks Euro` | +| 4 | `InternalResourcesName` | `Internal Resources` | +| 5 | `ProfitOrLossName` | `Profit or Loss` | + +- **Before (original ES):** `Create ES GL Accounts.()` from `src/Apps/ES/ContosoCoffeeDemoDatasetES/app/DemoData/Finance/1.Setup Data/CreateESGLAccounts.Codeunit.al`. +- **After (ported):** [demo data/Country/ES/ESGLAccountNames.Codeunit.al](demo%20data/Country/ES/ESGLAccountNames.Codeunit.al) — codeunit 8276. +- **Used by:** [demo data/Country/ES/ESExpGLAccount.Codeunit.al](demo%20data/Country/ES/ESExpGLAccount.Codeunit.al), [demo data/Country/ES/ESExpPostingGrp.Codeunit.al](demo%20data/Country/ES/ESExpPostingGrp.Codeunit.al), [demo data/Country/ES/ESUpdEmployee.Codeunit.al](demo%20data/Country/ES/ESUpdEmployee.Codeunit.al), [demo data/Country/ES/ESUpdEmpPostingGrp.Codeunit.al](demo%20data/Country/ES/ESUpdEmpPostingGrp.Codeunit.al), [demo data/Country/ES/ESPostedExpReport.Codeunit.al](demo%20data/Country/ES/ESPostedExpReport.Codeunit.al). + +#### DK +| # | Label | Value | +|---|-------|-------| +| 1 | `EntwinetobaccospiritsName` | `Ent., Wine / Tobacco / Spirits` | +| 2 | `PrepaymentsAccruedCostsName` | `Prepayments - Accrued Costs` | +| 3 | `CentdiscrepanciesName` | `Cent Discrepancies` | +| 4 | `RestaurantdiningName` | `Restaurant Dining` | +| 5 | `MileagerateName` | `Mileage Rate` | +| 6 | `TravelingtradefairsetcName` | `Traveling, Trade Fairs etc.` | +| 7 | `AccountsPayablePostingName` | `Accounts Payables` | +| 8 | `BankName` | `Bank` | +| 9 | `DomesticsalesofgoodsandservicesName` | `Domestic Sales of Goods and Services` | + +- **Before (original DK):** `Create GL Acc. DK.()` from `src/Apps/DK/ContosoCoffeeDemoDatasetDK/app/DemoData/Finance/1.Setup Data/CreateGLAccDK.Codeunit.al`. +- **After (ported):** [demo data/Country/DK/DKGLAccountNames.Codeunit.al](demo%20data/Country/DK/DKGLAccountNames.Codeunit.al) — codeunit 8289. +- **Used by:** [demo data/Country/DK/DKExpGLAccount.Codeunit.al](demo%20data/Country/DK/DKExpGLAccount.Codeunit.al), [demo data/Country/DK/DKExpPostingGrp.Codeunit.al](demo%20data/Country/DK/DKExpPostingGrp.Codeunit.al), [demo data/Country/DK/DKUpdEmpPostingGrp.Codeunit.al](demo%20data/Country/DK/DKUpdEmpPostingGrp.Codeunit.al), [demo data/Country/DK/DKPostedExpReport.Codeunit.al](demo%20data/Country/DK/DKPostedExpReport.Codeunit.al). + +#### NZ, AU +None. Both countries' original apps only reference base W1 Contoso Coffee names (`EmployeesPayableName`, `BankLCYName`, etc.) which are available via `Create G/L Account` in the base `Contoso Coffee Demo Dataset`. + +#### FR +None (no ContosoCoffee-FR name-lookups). FR introduces three FR-unique local G/L accounts (`CompanyCreditCards=512900`, `ExpensePrepaymentAccount=486200`, `RentalCarExpenses=625130`) with local `Tok` labels declared inside [demo data/Country/FR/FRExpGLAccount.Codeunit.al](demo%20data/Country/FR/FRExpGLAccount.Codeunit.al) — same as the original per-country app's own local declarations. + +#### DE +| # | Label | Value | +|---|-------|-------| +| 1 | `BusinessaccountOperatingDomesticName` | `Business account, Operating, Domestic` | +| 2 | `SaleofResourcesName` | `Sale of Resource` | +| 3 | `AssetsintheformofprepaidexpensesName` | `Assets in the form of prepaid expenses` | +| 4 | `SalesInvoiceRoundingName` | `Sales Invoice Rounding` | +| 5 | `BoardandlodgingName` | `Board and lodging` | +| 6 | `MiscexternalexpensesName` | `Misc. external expenses` | +| 7 | `OthertravelexpensesName` | `Other travel expenses` | +| 8 | `RentalvehiclesName` | `Rental vehicles` | +| 9 | `BusinessEntertainingdeductibleName` | `Business Entertaining, deductible` | + +- **Before (original DE):** `Create DE GL Acc.()` from `src/Apps/DE/ContosoCoffeeDemoDatasetDE/app/DemoData/Finance/1.Setup data/CreateDEGLAcc.Codeunit.al`. +- **After (ported):** [demo data/Country/DE/DEGLAccountNames.Codeunit.al](demo%20data/Country/DE/DEGLAccountNames.Codeunit.al) — codeunit 8312. +- **Used by:** [demo data/Country/DE/DEExpPostingGrp.Codeunit.al](demo%20data/Country/DE/DEExpPostingGrp.Codeunit.al), [demo data/Country/DE/DEUpdEmpPostingGrp.Codeunit.al](demo%20data/Country/DE/DEUpdEmpPostingGrp.Codeunit.al), [demo data/Country/DE/DEPostedExpReport.Codeunit.al](demo%20data/Country/DE/DEPostedExpReport.Codeunit.al). + +DE also introduces one DE-unique local G/L account (`CompanyCreditCardsClearingAccount=3510`, label `'Company credit card clearing account'`) declared inside [demo data/Country/DE/DEExpGLAccount.Codeunit.al](demo%20data/Country/DE/DEExpGLAccount.Codeunit.al) — same as the original per-country app's own local declaration. + +#### AT +| # | Label | Value | +|---|-------|-------| +| 1 | `SettlementAccountCashBankName` | `Settlement account cash bank` | +| 2 | `SalesRevenuesResourcesExportName` | `Sales revenues resources export` | +| 3 | `TransportationThirdPartiesName` | `Transportation third parties` | +| 4 | `KilometerAllowanceName` | `Kilometer allowance` | +| 5 | `MealExpensesDomesticName` | `Meal expenses domestic` | +| 6 | `MealExpensesAbroadName` | `Meal expenses abroad` | +| 7 | `HospitalityDomesticDeductibleAmountName` | `Hospitality domestic deductible amount` | +| 8 | `OtherName` | `Other` | + +- **Before (original AT):** `Create AT GL Account.()` from `src/Apps/AT/ContosoCoffeeDemoDatasetAT/app/DemoData/Finance/1. Setup Data/CreateATGLAccount.Codeunit.al`. +- **After (ported):** [demo data/Country/AT/ATGLAccountNames.Codeunit.al](demo%20data/Country/AT/ATGLAccountNames.Codeunit.al) — codeunit 8324. +- **Used by:** [demo data/Country/AT/ATExpPostingGrp.Codeunit.al](demo%20data/Country/AT/ATExpPostingGrp.Codeunit.al), [demo data/Country/AT/ATUpdEmpPostingGrp.Codeunit.al](demo%20data/Country/AT/ATUpdEmpPostingGrp.Codeunit.al), [demo data/Country/AT/ATPostedExpReport.Codeunit.al](demo%20data/Country/AT/ATPostedExpReport.Codeunit.al). + +AT also introduces one AT-unique local G/L account (`CompanyCreditCardsClearingAccount=2830`, label `'Company credit card clearing account'`) declared inside [demo data/Country/AT/ATExpGLAccount.Codeunit.al](demo%20data/Country/AT/ATExpGLAccount.Codeunit.al) — same as the original per-country app's own local declaration. + +### Pattern C — AT event subscribers bind/unbind gating + +**Problem:** the original `ExpenseAgent_AT` app declared its +`OnDefineExpenseAccountNo` and `OnBeforeValidateCurrencyCodeInExpense` +subscribers as plain (non-Manual) event subscribers on +[AT Exp. Contoso Localization.Codeunit.al](../../../../AT/ExpenseAgent_AT/demo%20data/Demo%20Data/ATExpContosoLocalization.Codeunit.al) — safe because that app was only ever installed on the AT loc. In the +consolidated extension the same static registration would fire on every +locale, silently rewriting expense account numbers and currency codes for +non-AT companies. + +**Workaround:** move both subscribers into Manual `SingleInstance` codeunits +([demo data/Country/AT/ATPostedExpReport.Codeunit.al](demo%20data/Country/AT/ATPostedExpReport.Codeunit.al) 8335 and [demo data/Country/AT/ATCurrencySwapSub.Codeunit.al](demo%20data/Country/AT/ATCurrencySwapSub.Codeunit.al) 8336) and let the AT orchestrator +[demo data/Country/AT/ATCountryData.Codeunit.al](demo%20data/Country/AT/ATCountryData.Codeunit.al) `BindSubscription` / `UnbindSubscription` them around `CreateHistoricalData`. Same technique used by FR and DE for their currency-swap and historical-account overrides. + +### ID collision — 8333, 8334, 8347, 8348 reserved by System Application + +The demo data extension's `idRanges` in [demo data/app.json](demo%20data/app.json) is `8201-8399`, but four codeunits inside that range are shipped by the base **System Application** and cannot be redefined here: + +| ID | System Application object | +|---|---| +| 8333 | `VS Code Integration Impl.` | +| 8334 | `VS Code Integration` | +| 8347 | `Feature Configuration` | +| 8348 | `Feature Configuration Impl.` | + +AT files that would naturally have received the next sequential IDs 8333/8334 were shifted to **8335 (`AT Posted Exp. Report`)** and **8336 (`AT Currency Swap Sub`)** for that reason. + +--- + +### Pattern B — ES `"Income Stmt. Bal. Acc."` late-bound field write + +**Problem:** the original `ExpenseAgent_ES` app strongly types +`GLAccount.Validate("Income Stmt. Bal. Acc.", )` on 11 G/L accounts. +That field is added to table `G/L Account` by the ES localization pack +(unavailable in W1). Adding a dep on that pack would restrict the whole +consolidated extension to ES loc. + +**Before (original ES):** +`src/Apps/ES/ExpenseAgent_ES/demo data/Demo Data/1.Setup Data/CreateExpenseGLAccountES.Codeunit.al` line 78: +```al +GLAccount.Validate("Income Stmt. Bal. Acc.", IncomeStmtBalAcc); +``` + +**After (ported):** [demo data/Country/ES/ESExpGLAccount.Codeunit.al#L74-L96](demo%20data/Country/ES/ESExpGLAccount.Codeunit.al#L74-L96): +```al +local procedure UpdateIncomeStmtBalAcc(No: Code[20]; IncomeStmtBalAcc: Code[20]) +var + GLAccount: Record "G/L Account"; + RecRef: RecordRef; + FieldRef: FieldRef; + i: Integer; +begin + // "Income Stmt. Bal. Acc." is added by the ES localization to table G/L Account. + // Look it up dynamically via FieldRef so this demo data works without an ES-loc + // compile-time dependency; silently skip when the field is not present. + if not GLAccount.Get(No) then + exit; + + RecRef.GetTable(GLAccount); + for i := 1 to RecRef.FieldCount do begin + FieldRef := RecRef.FieldIndex(i); + if FieldRef.Name = 'Income Stmt. Bal. Acc.' then begin + FieldRef.Validate(IncomeStmtBalAcc); + RecRef.Modify(); + exit; + end; + end; +end; +``` + +**Behavior:** +- On an ES-loc install: the field is present, `FieldRef.Validate` fires, + demo data written is byte-identical to the original. +- On a non-ES install: the loop completes without finding the field, + `UpdateIncomeStmtBalAcc` no-ops. This is safe because on a non-ES install + the country resolver returns something other than `ES` and this codepath + is never reached anyway. + +**Caveat:** field name comparison is against the English identifier +`'Income Stmt. Bal. Acc.'`. If a future BC build renames this field's +`Name` property (unlikely — captions are separate from names), this +lookup would miss and no `Income Stmt. Bal. Acc.` would be written. + +--- + +## Countries with no judgment calls + +Countries where the port is a pure 1:1 rename/renumber with no +technique changes: + +- **NZ** ([demo data/Country/NZ/](demo%20data/Country/NZ/)): base W1 names only. +- **AU** ([demo data/Country/AU/](demo%20data/Country/AU/)): base W1 names only. +- **FR** ([demo data/Country/FR/](demo%20data/Country/FR/)): base W1 names only; three FR-local G/L accounts inlined verbatim from the original per-country app. + +All ten countries ported. diff --git a/src/Apps/W1/ExpenseAgent/demo data/Country/US/USCountryData.Codeunit.al b/src/Apps/W1/ExpenseAgent/demo data/Country/US/USCountryData.Codeunit.al new file mode 100644 index 00000000000..5f8dab09554 --- /dev/null +++ b/src/Apps/W1/ExpenseAgent/demo data/Country/US/USCountryData.Codeunit.al @@ -0,0 +1,61 @@ +// ------------------------------------------------------------------------------------------------ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. See License.txt in the project root for license information. +// ------------------------------------------------------------------------------------------------ +namespace Microsoft.ExpenseAgent; + +codeunit 8223 "US Country Data" implements "Expense Agent Country Data" +{ + Access = Internal; + InherentEntitlements = X; + InherentPermissions = X; + + procedure CreateSetupData() + var + W1CountryData: Codeunit "W1 Country Data"; + USExpGLAccount: Codeunit "US Exp. GL Account"; + USExpPostingGrp: Codeunit "US Exp. Posting Grp"; + begin + BindSubscription(USExpGLAccount); + BindSubscription(USExpPostingGrp); + + W1CountryData.CreateSetupData(); + Codeunit.Run(Codeunit::"US Upd. Emp. Posting Grp"); + Codeunit.Run(Codeunit::"US Exp. Posting Grp"); + + UnbindSubscription(USExpPostingGrp); + UnbindSubscription(USExpGLAccount); + end; + + procedure CreateMasterData() + var + W1CountryData: Codeunit "W1 Country Data"; + begin + W1CountryData.CreateMasterData(); + Codeunit.Run(Codeunit::"US Exp. Categories"); + Codeunit.Run(Codeunit::"US Exp. SubCategories"); + Codeunit.Run(Codeunit::"US Exp. Rule Header"); + Codeunit.Run(Codeunit::"US Exp. Rule Condition"); + end; + + procedure CreateTransactionalData() + var + W1CountryData: Codeunit "W1 Country Data"; + begin + W1CountryData.CreateTransactionalData(); + Codeunit.Run(Codeunit::"US Expense"); + end; + + procedure CreateHistoricalData() + var + W1CountryData: Codeunit "W1 Country Data"; + USPostedExpReport: Codeunit "US Posted Exp. Report"; + begin + BindSubscription(USPostedExpReport); + + W1CountryData.CreateHistoricalData(); + Codeunit.Run(Codeunit::"US Posted Exp. Report"); + + UnbindSubscription(USPostedExpReport); + end; +} diff --git a/src/Apps/W1/ExpenseAgent/demo data/Country/US/USExpCategories.Codeunit.al b/src/Apps/W1/ExpenseAgent/demo data/Country/US/USExpCategories.Codeunit.al new file mode 100644 index 00000000000..c43bc444861 --- /dev/null +++ b/src/Apps/W1/ExpenseAgent/demo data/Country/US/USExpCategories.Codeunit.al @@ -0,0 +1,31 @@ +// ------------------------------------------------------------------------------------------------ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. See License.txt in the project root for license information. +// ------------------------------------------------------------------------------------------------ +namespace Microsoft.ExpenseAgent; + +codeunit 8227 "US Exp. Categories" +{ + InherentEntitlements = X; + InherentPermissions = X; + + trigger OnRun() + var + CreateExpenseGroup: Codeunit "Create Expense Group"; + CreateExpensePaymentMethod: Codeunit "Create Expense Payment Method"; + ContosoExpenseAgent: Codeunit "Contoso Expense Agent"; + USExpPostingGrp: Codeunit "US Exp. Posting Grp"; + begin + ContosoExpenseAgent.InsertExpenseCategory(PerDiem(), PerDiemByAssignedPolicyLbl, PerDiemByAssignedPolicyPostingLbl, USExpPostingGrp.ExpensePerDiem(), Enum::"Expense Attachment Enforcement"::" ", CreateExpensePaymentMethod.Cash(), false, false, CreateExpenseGroup.Travel(), true, Enum::"Expense Reimbursement Type"::"Employee Paid", Enum::"Expense Detail Needed"::"Per Diem"); + end; + + var + PerDiemTok: Label 'PER-DIEM', MaxLength = 20, Locked = true; + PerDiemByAssignedPolicyLbl: Label 'Expenses for per-diem or daily allowance paid for business trips, typically based on travel itinerary or other proof of travel (e.g., booking or agenda), rather than individual expense receipts.', MaxLength = 250; + PerDiemByAssignedPolicyPostingLbl: Label 'Per-diem by assigned policy', MaxLength = 100; + + procedure PerDiem(): Code[20] + begin + exit(PerDiemTok); + end; +} diff --git a/src/Apps/W1/ExpenseAgent/demo data/Country/US/USExpGLAccount.Codeunit.al b/src/Apps/W1/ExpenseAgent/demo data/Country/US/USExpGLAccount.Codeunit.al new file mode 100644 index 00000000000..f97f4886555 --- /dev/null +++ b/src/Apps/W1/ExpenseAgent/demo data/Country/US/USExpGLAccount.Codeunit.al @@ -0,0 +1,52 @@ +// ------------------------------------------------------------------------------------------------ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. See License.txt in the project root for license information. +// ------------------------------------------------------------------------------------------------ +namespace Microsoft.ExpenseAgent; + +using Microsoft.DemoTool.Helpers; +using Microsoft.Finance.GeneralLedger.Account; +using Microsoft.Foundation.Enums; + +codeunit 8224 "US Exp. GL Account" +{ + SingleInstance = true; + EventSubscriberInstance = Manual; + InherentEntitlements = X; + InherentPermissions = X; + + [EventSubscriber(ObjectType::Codeunit, Codeunit::"Create Expense G/L Account", 'OnAfterAddGLAccountsForLocalization', '', false, false)] + local procedure ModifyGLAccount() + var + GLAccountCategory: Record "G/L Account Category"; + SubCategory: Text[80]; + begin + AddGLAccounts(); + + SubCategory := Format(GLAccountCategory."Account Category"::Assets, 80); + ContosoGLAccount.InsertGLAccount(ExpenseGLAccount.CompanyCreditCardsAccount(), ExpenseGLAccount.CompanyCreditCardsAccountName(), "G/L Account Income/Balance"::"Balance Sheet", Enum::"G/L Account Category"::Assets, SubCategory, Enum::"G/L Account Type"::Posting, '', '', '', 0, '', Enum::"General Posting Type"::" ", '', '', true, false, false); + + SubCategory := Format(GLAccountCategory."Account Category"::Expense, 80); + ContosoGLAccount.InsertGLAccount(ExpenseGLAccount.PerDiemTravelExpensesAccount(), ExpenseGLAccount.PerDiemTravelExpensesAccountName(), "G/L Account Income/Balance"::"Income Statement", Enum::"G/L Account Category"::Expense, SubCategory, Enum::"G/L Account Type"::Posting, '', '', '', 0, '', Enum::"General Posting Type"::Purchase, '', '', true, false, false); + ContosoGLAccount.InsertGLAccount(ExpenseGLAccount.MileageTravelExpensesAccount(), ExpenseGLAccount.MileageTravelExpensesAccountName(), "G/L Account Income/Balance"::"Income Statement", Enum::"G/L Account Category"::Expense, SubCategory, Enum::"G/L Account Type"::Posting, '', '', '', 0, '', Enum::"General Posting Type"::Purchase, '', '', true, false, false); + ContosoGLAccount.InsertGLAccount(ExpenseGLAccount.MealExpensesDeductibleAccount(), ExpenseGLAccount.MealExpensesDeductibleAccountName(), "G/L Account Income/Balance"::"Income Statement", Enum::"G/L Account Category"::Expense, SubCategory, Enum::"G/L Account Type"::Posting, '', '', '', 0, '', Enum::"General Posting Type"::Purchase, '', '', true, false, false); + ContosoGLAccount.InsertGLAccount(ExpenseGLAccount.MealExpensesNondeductibleAccount(), ExpenseGLAccount.MealExpensesNondeductibleAccountName(), "G/L Account Income/Balance"::"Income Statement", Enum::"G/L Account Category"::Expense, SubCategory, Enum::"G/L Account Type"::Posting, '', '', '', 0, '', Enum::"General Posting Type"::Purchase, '', '', true, false, false); + ContosoGLAccount.InsertGLAccount(ExpenseGLAccount.OtherNondeductibleTravelExpensesAccount(), ExpenseGLAccount.OtherNondeductibleTravelExpensesAccountName(), "G/L Account Income/Balance"::"Income Statement", Enum::"G/L Account Category"::Expense, SubCategory, Enum::"G/L Account Type"::Posting, '', '', '', 0, '', Enum::"General Posting Type"::Purchase, '', '', true, false, false); + ContosoGLAccount.InsertGLAccount(ExpenseGLAccount.MiscExternalExpensesNondeductibleAccount(), ExpenseGLAccount.MiscExternalExpensesNondeductibleAccountName(), "G/L Account Income/Balance"::"Income Statement", Enum::"G/L Account Category"::Expense, SubCategory, Enum::"G/L Account Type"::Posting, '', '', '', 0, '', Enum::"General Posting Type"::Purchase, '', '', true, false, false); + end; + + local procedure AddGLAccounts() + begin + ContosoGLAccount.AddAccountForLocalization(ExpenseGLAccount.CompanyCreditCardsAccountName(), '18600'); + ContosoGLAccount.AddAccountForLocalization(ExpenseGLAccount.PerDiemTravelExpensesAccountName(), '62350'); + ContosoGLAccount.AddAccountForLocalization(ExpenseGLAccount.MileageTravelExpensesAccountName(), '62360'); + ContosoGLAccount.AddAccountForLocalization(ExpenseGLAccount.MealExpensesDeductibleAccountName(), '62370'); + ContosoGLAccount.AddAccountForLocalization(ExpenseGLAccount.MealExpensesNondeductibleAccountName(), '62380'); + ContosoGLAccount.AddAccountForLocalization(ExpenseGLAccount.OtherNondeductibleTravelExpensesAccountName(), '62390'); + ContosoGLAccount.AddAccountForLocalization(ExpenseGLAccount.MiscExternalExpensesNondeductibleAccountName(), '68285'); + end; + + var + ContosoGLAccount: Codeunit "Contoso GL Account"; + ExpenseGLAccount: Codeunit "Create Expense G/L Account"; +} diff --git a/src/Apps/W1/ExpenseAgent/demo data/Country/US/USExpPostingGrp.Codeunit.al b/src/Apps/W1/ExpenseAgent/demo data/Country/US/USExpPostingGrp.Codeunit.al new file mode 100644 index 00000000000..3638e41b226 --- /dev/null +++ b/src/Apps/W1/ExpenseAgent/demo data/Country/US/USExpPostingGrp.Codeunit.al @@ -0,0 +1,63 @@ +// ------------------------------------------------------------------------------------------------ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. See License.txt in the project root for license information. +// ------------------------------------------------------------------------------------------------ +namespace Microsoft.ExpenseAgent; + +codeunit 8225 "US Exp. Posting Grp" +{ + SingleInstance = true; + EventSubscriberInstance = Manual; + InherentEntitlements = X; + InherentPermissions = X; + + trigger OnRun() + var + ContosoExpenseAgent: Codeunit "Contoso Expense Agent"; + begin + ContosoExpenseAgent.InsertExpensePostingGroup(ExpensePerDiem(), ExpensePerDiemLbl); + end; + + [EventSubscriber(ObjectType::Table, Database::"Expense Posting Group", 'OnBeforeInsertEvent', '', false, false)] + local procedure OnInsertRecord(var Rec: Record "Expense Posting Group") + var + USGLAccountNames: Codeunit "US GL Account Names"; + ExpenseGLAccount: Codeunit "Create Expense G/L Account"; + CreateExpensePostingGroup: Codeunit "Create Expense Posting Group"; + begin + case Rec.Code of + CreateExpensePostingGroup.ExpenseEntertainment(): + ValidateRecordFields(Rec, ExpenseGLAccount.FindGLAccountByName(USGLAccountNames.BusinessEntertainingDeductibleName()), ExpenseGLAccount.FindGLAccountByName(USGLAccountNames.OtherIncidentalRevenueName()), ExpenseGLAccount.FindGLAccountByName(USGLAccountNames.OtherPrepaidExpensesAndAccruedIncomeName()), ExpenseGLAccount.FindGLAccountByName(USGLAccountNames.PayableInvoiceRoundingName()), ExpenseGLAccount.FindGLAccountByName(USGLAccountNames.PayableInvoiceRoundingName())); + CreateExpensePostingGroup.ExpenseMeals(): + ValidateRecordFields(Rec, ExpenseGLAccount.MealExpensesDeductibleAccount(), ExpenseGLAccount.FindGLAccountByName(USGLAccountNames.OtherIncidentalRevenueName()), ExpenseGLAccount.FindGLAccountByName(USGLAccountNames.OtherPrepaidExpensesAndAccruedIncomeName()), ExpenseGLAccount.FindGLAccountByName(USGLAccountNames.PayableInvoiceRoundingName()), ExpenseGLAccount.FindGLAccountByName(USGLAccountNames.PayableInvoiceRoundingName())); + CreateExpensePostingGroup.ExpenseMileage(): + ValidateRecordFields(Rec, ExpenseGLAccount.MileageTravelExpensesAccount(), '', ExpenseGLAccount.FindGLAccountByName(USGLAccountNames.OtherPrepaidExpensesAndAccruedIncomeName()), ExpenseGLAccount.FindGLAccountByName(USGLAccountNames.PayableInvoiceRoundingName()), ExpenseGLAccount.FindGLAccountByName(USGLAccountNames.PayableInvoiceRoundingName())); + CreateExpensePostingGroup.ExpenseOther(): + ValidateRecordFields(Rec, ExpenseGLAccount.FindGLAccountByName(USGLAccountNames.MiscExternalExpensesName()), ExpenseGLAccount.FindGLAccountByName(USGLAccountNames.OtherIncidentalRevenueName()), ExpenseGLAccount.FindGLAccountByName(USGLAccountNames.OtherPrepaidExpensesAndAccruedIncomeName()), ExpenseGLAccount.FindGLAccountByName(USGLAccountNames.PayableInvoiceRoundingName()), ExpenseGLAccount.FindGLAccountByName(USGLAccountNames.PayableInvoiceRoundingName())); + ExpensePerDiem(): + ValidateRecordFields(Rec, ExpenseGLAccount.PerDiemTravelExpensesAccount(), '', ExpenseGLAccount.FindGLAccountByName(USGLAccountNames.OtherPrepaidExpensesAndAccruedIncomeName()), ExpenseGLAccount.FindGLAccountByName(USGLAccountNames.PayableInvoiceRoundingName()), ExpenseGLAccount.FindGLAccountByName(USGLAccountNames.PayableInvoiceRoundingName())); + CreateExpensePostingGroup.ExpenseTravel(): + ValidateRecordFields(Rec, ExpenseGLAccount.FindGLAccountByName(USGLAccountNames.OtherTravelExpensesName()), ExpenseGLAccount.FindGLAccountByName(USGLAccountNames.OtherIncidentalRevenueName()), ExpenseGLAccount.FindGLAccountByName(USGLAccountNames.OtherPrepaidExpensesAndAccruedIncomeName()), ExpenseGLAccount.FindGLAccountByName(USGLAccountNames.PayableInvoiceRoundingName()), ExpenseGLAccount.FindGLAccountByName(USGLAccountNames.PayableInvoiceRoundingName())); + CreateExpensePostingGroup.ExpenseRentalCars(): + ValidateRecordFields(Rec, ExpenseGLAccount.FindGLAccountByName(USGLAccountNames.RentalVehiclesName()), ExpenseGLAccount.FindGLAccountByName(USGLAccountNames.OtherIncidentalRevenueName()), ExpenseGLAccount.FindGLAccountByName(USGLAccountNames.OtherPrepaidExpensesAndAccruedIncomeName()), ExpenseGLAccount.FindGLAccountByName(USGLAccountNames.PayableInvoiceRoundingName()), ExpenseGLAccount.FindGLAccountByName(USGLAccountNames.PayableInvoiceRoundingName())); + end; + end; + + local procedure ValidateRecordFields(var ExpensePostingGroup: Record "Expense Posting Group"; RefundableDebitAccount: Code[20]; NonRefundableDebitAccount: Code[20]; PrepaymentCreditAccount: Code[20]; ExpenseDebitRoundingAccount: Code[20]; ExpenseCreditRoundingAccount: Code[20]) + begin + ExpensePostingGroup.Validate("Refundable Debit Account", RefundableDebitAccount); + ExpensePostingGroup.Validate("Non-Refundable Debit Account", NonRefundableDebitAccount); + ExpensePostingGroup.Validate("Prepayment Credit Account", PrepaymentCreditAccount); + ExpensePostingGroup.Validate("Debit Rounding Account", ExpenseDebitRoundingAccount); + ExpensePostingGroup.Validate("Credit Rounding Account", ExpenseCreditRoundingAccount); + end; + + var + ExpensePERDIEMTok: Label 'EXPENSE-PERDIEM', MaxLength = 20, Locked = true; + ExpensePerDiemLbl: Label 'Expense - Per Diem', MaxLength = 100; + + procedure ExpensePerDiem(): Code[20] + begin + exit(ExpensePERDIEMTok); + end; +} diff --git a/src/Apps/W1/ExpenseAgent/demo data/Country/US/USExpRuleCondition.Codeunit.al b/src/Apps/W1/ExpenseAgent/demo data/Country/US/USExpRuleCondition.Codeunit.al new file mode 100644 index 00000000000..fd885936d20 --- /dev/null +++ b/src/Apps/W1/ExpenseAgent/demo data/Country/US/USExpRuleCondition.Codeunit.al @@ -0,0 +1,26 @@ +// ------------------------------------------------------------------------------------------------ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. See License.txt in the project root for license information. +// ------------------------------------------------------------------------------------------------ +namespace Microsoft.ExpenseAgent; + +codeunit 8230 "US Exp. Rule Condition" +{ + InherentEntitlements = X; + InherentPermissions = X; + + trigger OnRun() + var + USExpCategories: Codeunit "US Exp. Categories"; + CreateExpenseLocation: Codeunit "Create Expense Location"; + ContosoExpenseAgent: Codeunit "Contoso Expense Agent"; + begin + ContosoExpenseAgent.InsertExpenseRuleCondition(USExpCategories.PerDiem(), CreateExpenseLocation.CanadaAll(), 0D, 10000, Enum::"Expense Rule Condition Type"::"Daily Rate", 125); + ContosoExpenseAgent.InsertExpenseRuleCondition(USExpCategories.PerDiem(), CreateExpenseLocation.DenmarkAll(), 0D, 10000, Enum::"Expense Rule Condition Type"::"Daily Rate", 450); + ContosoExpenseAgent.InsertExpenseRuleCondition(USExpCategories.PerDiem(), CreateExpenseLocation.Domestic(), 0D, 10000, Enum::"Expense Rule Condition Type"::"Daily Rate", 50); + ContosoExpenseAgent.InsertExpenseRuleCondition(USExpCategories.PerDiem(), CreateExpenseLocation.FranceAll(), 0D, 10000, Enum::"Expense Rule Condition Type"::"Daily Rate", 110); + ContosoExpenseAgent.InsertExpenseRuleCondition(USExpCategories.PerDiem(), CreateExpenseLocation.GermanyAll(), 0D, 10000, Enum::"Expense Rule Condition Type"::"Daily Rate", 105); + ContosoExpenseAgent.InsertExpenseRuleCondition(USExpCategories.PerDiem(), CreateExpenseLocation.UKOther(), 0D, 10000, Enum::"Expense Rule Condition Type"::"Daily Rate", 115); + ContosoExpenseAgent.InsertExpenseRuleCondition(USExpCategories.PerDiem(), CreateExpenseLocation.USAOther(), 0D, 10000, Enum::"Expense Rule Condition Type"::"Daily Rate", 120); + end; +} diff --git a/src/Apps/W1/ExpenseAgent/demo data/Country/US/USExpRuleHeader.Codeunit.al b/src/Apps/W1/ExpenseAgent/demo data/Country/US/USExpRuleHeader.Codeunit.al new file mode 100644 index 00000000000..371f4aed2f9 --- /dev/null +++ b/src/Apps/W1/ExpenseAgent/demo data/Country/US/USExpRuleHeader.Codeunit.al @@ -0,0 +1,29 @@ +// ------------------------------------------------------------------------------------------------ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. See License.txt in the project root for license information. +// ------------------------------------------------------------------------------------------------ +namespace Microsoft.ExpenseAgent; + +using Microsoft.DemoData.Finance; + +codeunit 8229 "US Exp. Rule Header" +{ + InherentEntitlements = X; + InherentPermissions = X; + + trigger OnRun() + var + CreateCurrency: Codeunit "Create Currency"; + USExpCategories: Codeunit "US Exp. Categories"; + CreateExpenseLocation: Codeunit "Create Expense Location"; + ContosoExpenseAgent: Codeunit "Contoso Expense Agent"; + begin + ContosoExpenseAgent.InsertExpenseRuleHeader(USExpCategories.PerDiem(), CreateExpenseLocation.CanadaAll(), 0D, Enum::"Expense Justification"::" ", false, '', CreateCurrency.CAD(), ''); + ContosoExpenseAgent.InsertExpenseRuleHeader(USExpCategories.PerDiem(), CreateExpenseLocation.DenmarkAll(), 0D, Enum::"Expense Justification"::" ", false, '', CreateCurrency.EUR(), ''); + ContosoExpenseAgent.InsertExpenseRuleHeader(USExpCategories.PerDiem(), CreateExpenseLocation.Domestic(), 0D, Enum::"Expense Justification"::" ", false, '', '', ''); + ContosoExpenseAgent.InsertExpenseRuleHeader(USExpCategories.PerDiem(), CreateExpenseLocation.FranceAll(), 0D, Enum::"Expense Justification"::" ", false, '', CreateCurrency.EUR(), ''); + ContosoExpenseAgent.InsertExpenseRuleHeader(USExpCategories.PerDiem(), CreateExpenseLocation.GermanyAll(), 0D, Enum::"Expense Justification"::" ", false, '', CreateCurrency.EUR(), ''); + ContosoExpenseAgent.InsertExpenseRuleHeader(USExpCategories.PerDiem(), CreateExpenseLocation.UKOther(), 0D, Enum::"Expense Justification"::" ", false, '', CreateCurrency.GBP(), ''); + ContosoExpenseAgent.InsertExpenseRuleHeader(USExpCategories.PerDiem(), CreateExpenseLocation.USAOther(), 0D, Enum::"Expense Justification"::" ", false, '', '', ''); + end; +} diff --git a/src/Apps/W1/ExpenseAgent/demo data/Country/US/USExpSubCategories.Codeunit.al b/src/Apps/W1/ExpenseAgent/demo data/Country/US/USExpSubCategories.Codeunit.al new file mode 100644 index 00000000000..e9d714fe328 --- /dev/null +++ b/src/Apps/W1/ExpenseAgent/demo data/Country/US/USExpSubCategories.Codeunit.al @@ -0,0 +1,39 @@ +// ------------------------------------------------------------------------------------------------ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. See License.txt in the project root for license information. +// ------------------------------------------------------------------------------------------------ +namespace Microsoft.ExpenseAgent; + +codeunit 8228 "US Exp. SubCategories" +{ + InherentEntitlements = X; + InherentPermissions = X; + + trigger OnRun() + var + ContosoExpenseAgent: Codeunit "Contoso Expense Agent"; + USExpCategories: Codeunit "US Exp. Categories"; + begin + // PER-DIEM subcategories + ContosoExpenseAgent.InsertExpenseSubcategory(Country(), USExpCategories.PerDiem(), LocalCountryPerDiemLbl, LocalCountryPerDiemPostingLbl, false, true, false); + ContosoExpenseAgent.InsertExpenseSubcategory(Intl(), USExpCategories.PerDiem(), InternationalPerDiemLbl, InternationalPerDiemPostingLbl, false, true, false); + end; + + var + CountryTok: Label 'COUNTRY', MaxLength = 20, Locked = true; + IntlTok: Label 'INTL', MaxLength = 20, Locked = true; + LocalCountryPerDiemLbl: Label 'Daily per-diem allowance based on domestic travel rates, paid instead of individual meal or incidental expense reimbursements.', MaxLength = 250; + InternationalPerDiemLbl: Label 'Daily per-diem allowance for international business travel, based on applicable foreign travel rates.', MaxLength = 250; + LocalCountryPerDiemPostingLbl: Label 'Local country per-diem', MaxLength = 100; + InternationalPerDiemPostingLbl: Label 'International per-diem', MaxLength = 100; + + procedure Country(): Code[20] + begin + exit(CountryTok); + end; + + procedure Intl(): Code[20] + begin + exit(IntlTok); + end; +} diff --git a/src/Apps/W1/ExpenseAgent/demo data/Country/US/USExpense.Codeunit.al b/src/Apps/W1/ExpenseAgent/demo data/Country/US/USExpense.Codeunit.al new file mode 100644 index 00000000000..01c114bfe84 --- /dev/null +++ b/src/Apps/W1/ExpenseAgent/demo data/Country/US/USExpense.Codeunit.al @@ -0,0 +1,51 @@ +// ------------------------------------------------------------------------------------------------ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. See License.txt in the project root for license information. +// ------------------------------------------------------------------------------------------------ +namespace Microsoft.ExpenseAgent; + +using Microsoft.DemoTool.Helpers; + +codeunit 8231 "US Expense" +{ + InherentEntitlements = X; + InherentPermissions = X; + Permissions = tabledata "Expense Per Diem" = rim; + + trigger OnRun() + begin + CreateOpenExpense(); + end; + + local procedure CreateOpenExpense() + var + Expense: Record Expense; + ContosoExpenseAgent: Codeunit "Contoso Expense Agent"; + CreateExpenseLocation: Codeunit "Create Expense Location"; + begin + Expense := ContosoExpenseAgent.InsertExpense(CreateExpenseUser.EH(), USExpCategories.PerDiem(), CreateExpenseLocation.DenmarkAll(), PerDiemByAssignedPolicyLbl, '', ContosoUtility.AdjustDate(19030203D), '', 0, '', CreateExpensePaymentMethod.Cash(), true, false, '', CreateDateTime(ContosoUtility.AdjustDate(19030115D), 144000T), CreateDateTime(ContosoUtility.AdjustDate(19030121D), 000500T), 0, 0, '', '', '', '', ''); + UpdateExpensePerDiem(Expense."No.", 10000, false, false, true); + UpdateExpensePerDiem(Expense."No.", 30000, false, true, false); + UpdateExpensePerDiem(Expense."No.", 40000, false, false, true); + UpdateExpensePerDiem(Expense."No.", 60000, false, true, true); + end; + + var + ContosoUtility: Codeunit "Contoso Utilities"; + CreateExpenseUser: Codeunit "Create Expense User"; + USExpCategories: Codeunit "US Exp. Categories"; + CreateExpensePaymentMethod: Codeunit "Create Expense Payment Method"; + PerDiemByAssignedPolicyLbl: Label 'Per-diem by assigned policy', MaxLength = 100; + + local procedure UpdateExpensePerDiem(ExpenseNo: Code[20]; LineNo: Integer; Breakfast: Boolean; Lunch: Boolean; Dinner: Boolean) + var + ExpensePerDiem: Record "Expense Per Diem"; + begin + ExpensePerDiem.Get(ExpenseNo, LineNo); + + ExpensePerDiem.Validate(Breakfast, Breakfast); + ExpensePerDiem.Validate(Lunch, Lunch); + ExpensePerDiem.Validate(Dinner, Dinner); + ExpensePerDiem.Modify(); + end; +} diff --git a/src/Apps/W1/ExpenseAgent/demo data/Country/US/USGLAccountNames.Codeunit.al b/src/Apps/W1/ExpenseAgent/demo data/Country/US/USGLAccountNames.Codeunit.al new file mode 100644 index 00000000000..f27e4e6c052 --- /dev/null +++ b/src/Apps/W1/ExpenseAgent/demo data/Country/US/USGLAccountNames.Codeunit.al @@ -0,0 +1,74 @@ +// ------------------------------------------------------------------------------------------------ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. See License.txt in the project root for license information. +// ------------------------------------------------------------------------------------------------ +namespace Microsoft.ExpenseAgent; + +codeunit 8220 "US GL Account Names" +{ + Access = Internal; + InherentEntitlements = X; + InherentPermissions = X; + + var + BusinessEntertainingDeductibleTok: Label 'Business Entertaining, deductible', MaxLength = 100; + OtherIncidentalRevenueTok: Label 'Other Incidental Revenue', MaxLength = 100; + OtherPrepaidExpensesAndAccruedIncomeTok: Label 'Other prepaid expenses and accrued income', MaxLength = 100; + PayableInvoiceRoundingTok: Label 'Payable Invoice Rounding', MaxLength = 100; + MiscExternalExpensesTok: Label 'Misc. external expenses', MaxLength = 100; + OtherTravelExpensesTok: Label 'Other travel expenses', MaxLength = 100; + RentalVehiclesTok: Label 'Rental vehicles', MaxLength = 100; + AccountsPayableDomesticTok: Label 'Accounts Payable, Domestic', MaxLength = 100; + OtherBankAccountsTok: Label 'Other bank accounts ', MaxLength = 100; + SaleofResourcesTok: Label 'Sale of Resources', MaxLength = 100; + + procedure BusinessEntertainingDeductibleName(): Text[100] + begin + exit(BusinessEntertainingDeductibleTok); + end; + + procedure OtherIncidentalRevenueName(): Text[100] + begin + exit(OtherIncidentalRevenueTok); + end; + + procedure OtherPrepaidExpensesAndAccruedIncomeName(): Text[100] + begin + exit(OtherPrepaidExpensesAndAccruedIncomeTok); + end; + + procedure PayableInvoiceRoundingName(): Text[100] + begin + exit(PayableInvoiceRoundingTok); + end; + + procedure MiscExternalExpensesName(): Text[100] + begin + exit(MiscExternalExpensesTok); + end; + + procedure OtherTravelExpensesName(): Text[100] + begin + exit(OtherTravelExpensesTok); + end; + + procedure RentalVehiclesName(): Text[100] + begin + exit(RentalVehiclesTok); + end; + + procedure AccountsPayableDomesticName(): Text[100] + begin + exit(AccountsPayableDomesticTok); + end; + + procedure OtherBankAccountsName(): Text[100] + begin + exit(OtherBankAccountsTok); + end; + + procedure SaleofResourcesName(): Text[100] + begin + exit(SaleofResourcesTok); + end; +} diff --git a/src/Apps/W1/ExpenseAgent/demo data/Country/US/USPostedExpReport.Codeunit.al b/src/Apps/W1/ExpenseAgent/demo data/Country/US/USPostedExpReport.Codeunit.al new file mode 100644 index 00000000000..0452bed56b2 --- /dev/null +++ b/src/Apps/W1/ExpenseAgent/demo data/Country/US/USPostedExpReport.Codeunit.al @@ -0,0 +1,168 @@ +// ------------------------------------------------------------------------------------------------ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. See License.txt in the project root for license information. +// ------------------------------------------------------------------------------------------------ +namespace Microsoft.ExpenseAgent; + +using Microsoft.DemoData.Finance; +using Microsoft.DemoData.HumanResources; +using Microsoft.DemoTool.Helpers; + +codeunit 8232 "US Posted Exp. Report" +{ + SingleInstance = true; + EventSubscriberInstance = Manual; + InherentEntitlements = X; + InherentPermissions = X; + Permissions = + tabledata "Expense Per Diem" = rim, + tabledata "Expense Report Line" = rim; + + trigger OnRun() + var + ExpenseReportHeader: Record "Expense Report Header"; + begin + if ExpenseReportHeader.FindLast() then + FromExpenseReportNo := ExpenseReportHeader."No."; + + CreateExpenseReportToPost(); + + PostExpenseReport(); + end; + + [EventSubscriber(ObjectType::Codeunit, Codeunit::"Create Posted Expense Report", OnDefineExpenseAccountNo, '', false, false)] + local procedure OnDefineExpenseAccountNo(var AccountNo: Code[20]) + var + USGLAccountNames: Codeunit "US GL Account Names"; + ExpenseGLAccount: Codeunit "Create Expense G/L Account"; + begin + AccountNo := ExpenseGLAccount.FindGLAccountByName(USGLAccountNames.SaleofResourcesName()); + end; + + local procedure CreateExpenseReportToPost() + var + Expense: Record Expense; + ExpenseReportHeader: Record "Expense Report Header"; + CreateEmployee: Codeunit "Create Employee"; + CreateCurrency: Codeunit "Create Currency"; + ContosoUtility: Codeunit "Contoso Utilities"; + CreateExpenseUser: Codeunit "Create Expense User"; + CreateExpenseLocation: Codeunit "Create Expense Location"; + ContosoExpenseAgent: Codeunit "Contoso Expense Agent"; + CreateExpCategories: Codeunit "Create Expense Categories DM"; + USExpCategories: Codeunit "US Exp. Categories"; + CreateExpenseSubcategories: Codeunit "Create Expense Subcategories"; + CreateExpensePaymentMethod: Codeunit "Create Expense Payment Method"; + begin + ExpenseReportHeader := ContosoExpenseAgent.InsertExpenseReportHeader(CreateExpenseUser.JO(), ContosoUtility.AdjustDate(19021104D), ContosoUtility.AdjustDate(19021104D)); + Expense := ContosoExpenseAgent.InsertExpense(CreateExpenseUser.JO(), USExpCategories.PerDiem(), CreateExpenseLocation.GermanyAll(), BusinessTripToHamburgLbl, '', ContosoUtility.AdjustDate(19021103D), '', 0, '', CreateExpensePaymentMethod.Cash(), true, false, '', CreateDateTime(ContosoUtility.AdjustDate(19021024D), 064500T), CreateDateTime(ContosoUtility.AdjustDate(19021027D), 161500T), 0, 0, '', '', '', '', ''); + ReleaseAndAddExpenseToExpenseReport(Expense, ExpenseReportHeader); + Expense := ContosoExpenseAgent.InsertExpense(CreateExpenseUser.JO(), CreateExpCategories.Airline(), '', AirlineTicketsLbl, '', ContosoUtility.AdjustDate(19021010D), '', 2042, MargieTravelLbl, CreateExpensePaymentMethod.Card(), true, false, '', 0DT, 0DT, 0, 0, '', '', 'TY6HJO', '', ''); + ReleaseAndAddExpenseToExpenseReport(Expense, ExpenseReportHeader); + + ExpenseReportHeader := ContosoExpenseAgent.InsertExpenseReportHeader(CreateExpenseUser.EH(), ContosoUtility.AdjustDate(19021204D), ContosoUtility.AdjustDate(19021204D)); + Expense := ContosoExpenseAgent.InsertExpense(CreateExpenseUser.EH(), CreateExpCategories.Airline(), '', AirlineTicketsDublinLbl, TravelToConferenceLbl, ContosoUtility.AdjustDate(19021106D), '', 3120, MargieTravelLbl, CreateExpensePaymentMethod.Card(), true, false, '', 0DT, 0DT, 0, 0, '', '', 'FIUXHJT', '', ''); + ReleaseAndAddExpenseToExpenseReport(Expense, ExpenseReportHeader); + Expense := ContosoExpenseAgent.InsertExpense(CreateExpenseUser.EH(), CreateExpCategories.Events(), '', ITConferenceLbl, '', ContosoUtility.AdjustDate(19021107D), CreateCurrency.EUR(), 1990, ProsewareIncLbl, CreateExpensePaymentMethod.Card(), true, false, '', 0DT, 0DT, 0, 0, '', '', 'G574576HJ656', '', ''); + ReleaseAndAddExpenseToExpenseReport(Expense, ExpenseReportHeader); + Expense := ContosoExpenseAgent.InsertExpense(CreateExpenseUser.EH(), CreateExpCategories.GroundTransportation(), '', TaxiLbl, '', ContosoUtility.AdjustDate(19021114D), CreateCurrency.EUR(), 45, TailwindTradersLbl, CreateExpensePaymentMethod.Cash(), true, false, '', 0DT, 0DT, 0, 0, '', '', '456845856867', '', ''); + ReleaseAndAddExpenseToExpenseReport(Expense, ExpenseReportHeader); + Expense := ContosoExpenseAgent.InsertExpense(CreateExpenseUser.EH(), CreateExpCategories.Entertain(), '', BusinessDinnerLbl, BusinessDinnerWithBigPotentialCustomersLbl, ContosoUtility.AdjustDate(19021116D), CreateCurrency.EUR(), 842, FourthCoffeeLbl, CreateExpensePaymentMethod.Card(), true, false, '', 0DT, 0DT, 0, 0, '', '', 'RT6457560034', '', ''); + ContosoExpenseAgent.InsertExpenseParticipant(Expense."No.", 10000, CreateExpCategories.Entertain(), Enum::"Expense Participant Type"::Employee, CreateEmployee.ManagingDirector(), '', '', '', '', ''); + ContosoExpenseAgent.InsertExpenseParticipant(Expense."No.", 20000, CreateExpCategories.Entertain(), Enum::"Expense Participant Type"::Employee, CreateEmployee.SalesManager(), '', '', '', '', ''); + ContosoExpenseAgent.InsertExpenseParticipant(Expense."No.", 30000, CreateExpCategories.Entertain(), Enum::"Expense Participant Type"::External, '', JesseHomerLbl, RelecloudLbl, '', CEOLbl, 'jesse.homer@contoso.com'); + ContosoExpenseAgent.InsertExpenseParticipant(Expense."No.", 40000, CreateExpCategories.Entertain(), Enum::"Expense Participant Type"::External, '', RobertTownesLbl, AdatumCorporationLbl, '', CEOLbl, 'robert.townes@contoso.com'); + ReleaseAndAddExpenseToExpenseReport(Expense, ExpenseReportHeader); + Expense := ContosoExpenseAgent.InsertExpense(CreateExpenseUser.EH(), CreateExpCategories.Hotels(), '', HotelStayLbl, '', ContosoUtility.AdjustDate(19021118D), CreateCurrency.EUR(), 2150, ContosoSuitesLbl, CreateExpensePaymentMethod.Card(), true, false, '', 0DT, 0DT, 0, 0, '', '', '64675S879CT987990004', '', ''); + ContosoExpenseAgent.InsertExpenseItemization(Expense."No.", 10000, CreateExpCategories.Hotels(), CreateExpenseSubcategories.Room(), AccommodationLbl, ContosoUtility.AdjustDate(19021114D), 390); + ContosoExpenseAgent.InsertExpenseItemization(Expense."No.", 20000, CreateExpCategories.Hotels(), CreateExpenseSubcategories.Breakfast(), BreakfastLbl, ContosoUtility.AdjustDate(19021115D), 35); + ContosoExpenseAgent.InsertExpenseItemization(Expense."No.", 30000, CreateExpCategories.Hotels(), CreateExpenseSubcategories.Room(), AccommodationLbl, ContosoUtility.AdjustDate(19021115D), 390); + ContosoExpenseAgent.InsertExpenseItemization(Expense."No.", 40000, CreateExpCategories.Hotels(), CreateExpenseSubcategories.Breakfast(), BreakfastLbl, ContosoUtility.AdjustDate(19021116D), 35); + ContosoExpenseAgent.InsertExpenseItemization(Expense."No.", 50000, CreateExpCategories.Hotels(), CreateExpenseSubcategories.Room(), AccommodationLbl, ContosoUtility.AdjustDate(19021116D), 390); + ContosoExpenseAgent.InsertExpenseItemization(Expense."No.", 60000, CreateExpCategories.Hotels(), CreateExpenseSubcategories.RoomService(), RoomServiceLbl, ContosoUtility.AdjustDate(19021116D), 145); + ContosoExpenseAgent.InsertExpenseItemization(Expense."No.", 70000, CreateExpCategories.Hotels(), CreateExpenseSubcategories.Breakfast(), BreakfastLbl, ContosoUtility.AdjustDate(19021117D), 35); + ContosoExpenseAgent.InsertExpenseItemization(Expense."No.", 80000, CreateExpCategories.Hotels(), CreateExpenseSubcategories.Room(), AccommodationLbl, ContosoUtility.AdjustDate(19021117D), 390); + ContosoExpenseAgent.InsertExpenseItemization(Expense."No.", 90000, CreateExpCategories.Hotels(), CreateExpenseSubcategories.Breakfast(), BreakfastLbl, ContosoUtility.AdjustDate(19021118D), 35); + ContosoExpenseAgent.InsertExpenseItemization(Expense."No.", 100000, CreateExpCategories.Hotels(), CreateExpenseSubcategories.Tax(), HotelTaxesLbl, ContosoUtility.AdjustDate(19021118D), 305); + ReleaseAndAddExpenseToExpenseReport(Expense, ExpenseReportHeader); + Expense := ContosoExpenseAgent.InsertExpense(CreateExpenseUser.EH(), CreateExpCategories.RentalCars(), '', CarRentalsLbl, '', ContosoUtility.AdjustDate(19021118D), CreateCurrency.EUR(), 622.45, VanArsdelLtdLbl, CreateExpensePaymentMethod.Card(), true, false, '', 0DT, 0DT, 0, 0, '', '', 'H6584769867J9J95789', '', ''); + ReleaseAndAddExpenseToExpenseReport(Expense, ExpenseReportHeader); + Expense := ContosoExpenseAgent.InsertExpense(CreateExpenseUser.EH(), CreateExpCategories.GroundTransportation(), '', TaxiLbl, '', ContosoUtility.AdjustDate(19021118D), CreateCurrency.EUR(), 71, TailwindTradersLbl, CreateExpensePaymentMethod.Cash(), true, false, '', 0DT, 0DT, 0, 0, '', '', '7456875687568', '', ''); + ReleaseAndAddExpenseToExpenseReport(Expense, ExpenseReportHeader); + Expense := ContosoExpenseAgent.InsertExpense(CreateExpenseUser.EH(), USExpCategories.PerDiem(), CreateExpenseLocation.UKOther(), TripToUKLbl, '', ContosoUtility.AdjustDate(19021121D), '', 0, '', CreateExpensePaymentMethod.Cash(), true, false, '', CreateDateTime(ContosoUtility.AdjustDate(19021114D), 053000T), CreateDateTime(ContosoUtility.AdjustDate(19021118D), 220500T), 0, 0, '', '', '', '', ''); + UpdateExpensePerDiem(Expense."No.", 20000, false, false, true); + UpdateExpensePerDiem(Expense."No.", 40000, false, true, false); + ReleaseAndAddExpenseToExpenseReport(Expense, ExpenseReportHeader); + Expense := ContosoExpenseAgent.InsertExpense(CreateExpenseUser.EH(), USExpCategories.PerDiem(), CreateExpenseLocation.Domestic(), TripToDoverLbl, '', ContosoUtility.AdjustDate(19021204D), '', 0, '', CreateExpensePaymentMethod.Cash(), true, false, '', CreateDateTime(ContosoUtility.AdjustDate(19021127D), 070000T), CreateDateTime(ContosoUtility.AdjustDate(19021129D), 145500T), 0, 0, '', '', '', '', ''); + ReleaseAndAddExpenseToExpenseReport(Expense, ExpenseReportHeader); + Expense := ContosoExpenseAgent.InsertExpense(CreateExpenseUser.EH(), CreateExpCategories.Mileage(), '', MileageLbl, '', ContosoUtility.AdjustDate(19031101D), '', 0, VanArsdelLtdLbl, CreateExpensePaymentMethod.Cash(), true, false, '', 0DT, 0DT, 0, 249, 'New York', 'Dover', 'H6584769867J9J95789', '', ''); + ReleaseAndAddExpenseToExpenseReport(Expense, ExpenseReportHeader); + end; + + var + FromExpenseReportNo: Code[20]; + BusinessTripToHamburgLbl: Label 'Business trip to Hamburg, DE', MaxLength = 100; + AirlineTicketsLbl: Label 'Airline tickets NY/FRANKFURT/HAMBURG/FRANKFURT/NY', MaxLength = 100; + MargieTravelLbl: Label 'Margie''s Travel', MaxLength = 100; + AirlineTicketsDublinLbl: Label 'Airline tickets NY/DUBLIN/NY', MaxLength = 100; + TravelToConferenceLbl: Label 'Travel to the conference', MaxLength = 100; + ITConferenceLbl: Label 'IT Conference', MaxLength = 100; + ProsewareIncLbl: Label 'Proseware, Inc.', MaxLength = 100; + TaxiLbl: Label 'Taxi', MaxLength = 100; + TailwindTradersLbl: Label 'Tailwind Traders', MaxLength = 100; + BusinessDinnerLbl: Label 'Business Dinner', MaxLength = 100; + BusinessDinnerWithBigPotentialCustomersLbl: Label 'Business dinner with a big potential customers', MaxLength = 100; + FourthCoffeeLbl: Label 'Fourth Coffee', MaxLength = 100; + JesseHomerLbl: Label 'Jesse Homer', MaxLength = 100; + RelecloudLbl: Label 'Relecloud', MaxLength = 100; + RobertTownesLbl: Label 'Robert Townes', MaxLength = 100; + AdatumCorporationLbl: Label 'Adatum Corporation', MaxLength = 100; + HotelStayLbl: Label 'Hotel stay', MaxLength = 100; + ContosoSuitesLbl: Label 'Contoso Suites', MaxLength = 100; + AccommodationLbl: Label 'Accommodation', MaxLength = 100; + BreakfastLbl: Label 'Breakfast', MaxLength = 100; + HotelTaxesLbl: Label 'Hotel Taxes', MaxLength = 100; + RoomServiceLbl: Label 'Room service', MaxLength = 100; + CarRentalsLbl: Label 'Car Rentals', MaxLength = 100; + VanArsdelLtdLbl: Label 'VanArsdel, Ltd.', MaxLength = 100; + TripToUKLbl: Label 'Trip to UK', MaxLength = 100; + TripToDoverLbl: Label 'Trip to Dover', MaxLength = 100; + MileageLbl: Label 'Mileage', MaxLength = 100; + CEOLbl: Label 'CEO', MaxLength = 30; + + local procedure ReleaseAndAddExpenseToExpenseReport(Expense: Record Expense; ExpenseReportHeader: Record "Expense Report Header") + var + ReleaseExpenseDocument: Codeunit "Release Expense Document"; + CreateExpenseReport: Codeunit "Create Expense Report"; + begin + Expense.Get(Expense."No."); + ReleaseExpenseDocument.Run(Expense); + + CreateExpenseReport.AddSingleExpenseToExpenseReport(Expense, ExpenseReportHeader); + end; + + local procedure PostExpenseReport() + var + ExpenseReportHeader: Record "Expense Report Header"; + begin + if FromExpenseReportNo <> '' then + ExpenseReportHeader.SetFilter("No.", '>%1', FromExpenseReportNo); + + if ExpenseReportHeader.FindSet() then + repeat + Codeunit.Run(Codeunit::"Expense Report-Post", ExpenseReportHeader); + until ExpenseReportHeader.Next() = 0; + end; + + local procedure UpdateExpensePerDiem(ExpenseNo: Code[20]; LineNo: Integer; Breakfast: Boolean; Lunch: Boolean; Dinner: Boolean) + var + ExpensePerDiem: Record "Expense Per Diem"; + begin + ExpensePerDiem.Get(ExpenseNo, LineNo); + + ExpensePerDiem.Validate(Breakfast, Breakfast); + ExpensePerDiem.Validate(Lunch, Lunch); + ExpensePerDiem.Validate(Dinner, Dinner); + ExpensePerDiem.Modify(); + end; +} diff --git a/src/Apps/W1/ExpenseAgent/demo data/Country/US/USUpdEmpPostingGrp.Codeunit.al b/src/Apps/W1/ExpenseAgent/demo data/Country/US/USUpdEmpPostingGrp.Codeunit.al new file mode 100644 index 00000000000..6c8acc31157 --- /dev/null +++ b/src/Apps/W1/ExpenseAgent/demo data/Country/US/USUpdEmpPostingGrp.Codeunit.al @@ -0,0 +1,32 @@ +// ------------------------------------------------------------------------------------------------ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. See License.txt in the project root for license information. +// ------------------------------------------------------------------------------------------------ +namespace Microsoft.ExpenseAgent; + +using Microsoft.DemoData.Finance; +using Microsoft.DemoData.HumanResources; + +codeunit 8226 "US Upd. Emp. Posting Grp" +{ + InherentEntitlements = X; + InherentPermissions = X; + + trigger OnRun() + begin + UpdateEmployeePostingGroup(); + end; + + local procedure UpdateEmployeePostingGroup() + var + CreateGLAccount: Codeunit "Create G/L Account"; + ExpenseGLAccount: Codeunit "Create Expense G/L Account"; + USGLAccountNames: Codeunit "US GL Account Names"; + ContosoExpenseAgent: Codeunit "Contoso Expense Agent"; + CreateEmployeePostingGroup: Codeunit "Create Employee Posting Group"; + begin + ContosoExpenseAgent.SetOverwriteData(true); + ContosoExpenseAgent.UpdateEmployeePostingGroup(CreateEmployeePostingGroup.EmployeeExpenses(), ExpenseGLAccount.FindGLAccountByName(USGLAccountNames.AccountsPayableDomesticName()), ExpenseGLAccount.FindGLAccountByName(CreateGLAccount.CashName()), ExpenseGLAccount.FindGLAccountByName(USGLAccountNames.OtherBankAccountsName()), ExpenseGLAccount.CompanyCreditCardsAccount()); + ContosoExpenseAgent.SetOverwriteData(false); + end; +} diff --git a/src/Apps/W1/ExpenseAgent/demo data/Country/W1/W1CountryData.Codeunit.al b/src/Apps/W1/ExpenseAgent/demo data/Country/W1/W1CountryData.Codeunit.al new file mode 100644 index 00000000000..597990fe8e2 --- /dev/null +++ b/src/Apps/W1/ExpenseAgent/demo data/Country/W1/W1CountryData.Codeunit.al @@ -0,0 +1,44 @@ +// ------------------------------------------------------------------------------------------------ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. See License.txt in the project root for license information. +// ------------------------------------------------------------------------------------------------ +namespace Microsoft.ExpenseAgent; + +codeunit 8222 "W1 Country Data" implements "Expense Agent Country Data" +{ + Access = Internal; + InherentEntitlements = X; + InherentPermissions = X; + + procedure CreateSetupData() + begin + Codeunit.Run(Codeunit::"Create Expense Payment Method"); + Codeunit.Run(Codeunit::"Create Expense No. Series DM"); + Codeunit.Run(Codeunit::"Create Expense Group"); + Codeunit.Run(Codeunit::"Create Expense G/L Account"); + Codeunit.Run(Codeunit::"Create Expense Posting Group"); + Codeunit.Run(Codeunit::"Create Expense Team"); + Codeunit.Run(Codeunit::"Create Exp. Agent Setup"); + end; + + procedure CreateMasterData() + begin + Codeunit.Run(Codeunit::"Create Expense Location"); + Codeunit.Run(Codeunit::"Create Expense Categories DM"); + Codeunit.Run(Codeunit::"Create Expense Subcategories"); + Codeunit.Run(Codeunit::"Create Expense Rule Header"); + Codeunit.Run(Codeunit::"Create Expense Rule Condition"); + Codeunit.Run(Codeunit::"Create Expense User"); + end; + + procedure CreateTransactionalData() + begin + Codeunit.Run(Codeunit::"Create Expense"); + Codeunit.Run(Codeunit::"Create Exp. Report"); + end; + + procedure CreateHistoricalData() + begin + Codeunit.Run(Codeunit::"Create Posted Expense Report"); + end; +} diff --git a/src/Apps/W1/ExpenseAgent/demo data/Demo Data/ExpenseAgentContosoModule.Codeunit.al b/src/Apps/W1/ExpenseAgent/demo data/Demo Data/ExpenseAgentContosoModule.Codeunit.al index 77da9374d0f..cf268322849 100644 --- a/src/Apps/W1/ExpenseAgent/demo data/Demo Data/ExpenseAgentContosoModule.Codeunit.al +++ b/src/Apps/W1/ExpenseAgent/demo data/Demo Data/ExpenseAgentContosoModule.Codeunit.al @@ -26,35 +26,38 @@ codeunit 8202 "Expense Agent Contoso Module" implements "Contoso Demo Data Modul procedure CreateSetupData() var ExpenseAgentModuleSetup: Record "Expense Agent Module Setup"; + Resolver: Codeunit "Exp. Agent Country Resolver"; + CountryData: Interface "Expense Agent Country Data"; begin ExpenseAgentModuleSetup.InitRecord(); - Codeunit.Run(Codeunit::"Create Expense Payment Method"); - Codeunit.Run(Codeunit::"Create Expense No. Series DM"); - Codeunit.Run(Codeunit::"Create Expense Group"); - Codeunit.Run(Codeunit::"Create Expense G/L Account"); - Codeunit.Run(Codeunit::"Create Expense Posting Group"); - Codeunit.Run(Codeunit::"Create Expense Team"); - Codeunit.Run(Codeunit::"Create Exp. Agent Setup"); + CountryData := Resolver.Resolve(); + CountryData.CreateSetupData(); end; procedure CreateMasterData() + var + Resolver: Codeunit "Exp. Agent Country Resolver"; + CountryData: Interface "Expense Agent Country Data"; begin - Codeunit.Run(Codeunit::"Create Expense Location"); - Codeunit.Run(Codeunit::"Create Expense Categories DM"); - Codeunit.Run(Codeunit::"Create Expense Subcategories"); - Codeunit.Run(Codeunit::"Create Expense Rule Header"); - Codeunit.Run(Codeunit::"Create Expense Rule Condition"); - Codeunit.Run(Codeunit::"Create Expense User"); + CountryData := Resolver.Resolve(); + CountryData.CreateMasterData(); end; procedure CreateTransactionalData() + var + Resolver: Codeunit "Exp. Agent Country Resolver"; + CountryData: Interface "Expense Agent Country Data"; begin - Codeunit.Run(Codeunit::"Create Expense"); - Codeunit.Run(Codeunit::"Create Exp. Report"); + CountryData := Resolver.Resolve(); + CountryData.CreateTransactionalData(); end; procedure CreateHistoricalData() + var + Resolver: Codeunit "Exp. Agent Country Resolver"; + CountryData: Interface "Expense Agent Country Data"; begin - Codeunit.Run(Codeunit::"Create Posted Expense Report"); + CountryData := Resolver.Resolve(); + CountryData.CreateHistoricalData(); end; } \ No newline at end of file diff --git a/src/Apps/W1/ExpenseAgent/demo data/app.json b/src/Apps/W1/ExpenseAgent/demo data/app.json index 6567deda989..31d0ccf937b 100644 --- a/src/Apps/W1/ExpenseAgent/demo data/app.json +++ b/src/Apps/W1/ExpenseAgent/demo data/app.json @@ -83,7 +83,7 @@ "idRanges": [ { "from": 8201, - "to": 8222 + "to": 8399 } ], "target": "OnPrem",