diff --git a/.vscode/launch.json b/.vscode/launch.json index c8a1a591..bb97e1d2 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -49,7 +49,7 @@ "AYANOVA_USE_URLS": "http://*:7575;", //"AYANOVA_PERMANENTLY_ERASE_DATABASE":"true", //"AYANOVA_REMOVE_LICENSE_FROM_DB":"true", - "AYANOVA_SERVER_TEST_MODE": "false", + //"AYANOVA_SERVER_TEST_MODE": "true", "AYANOVA_SERVER_TEST_MODE_TZ_OFFSET": "-8", //"AYANOVA_REPORT_RENDERING_TIMEOUT":"1", "AYANOVA_SERVER_TEST_MODE_SEEDLEVEL": "small", diff --git a/devdocs/deploy.md b/devdocs/deploy.md index a72fc513..c06dd101 100644 --- a/devdocs/deploy.md +++ b/devdocs/deploy.md @@ -6,7 +6,7 @@ If any packages have been changed in the release do a thorough security scan and ### Bump version numbers: -Search and replace 8.0.2 +Search and replace 8.0.3 webapp,server,launcher, v8migrate (don't change v8migrate unless it has it's own code changes, it's version should be it's own thing other than major release changes etc) Client end ayanova-version.js, diff --git a/devdocs/pricing.md b/devdocs/pricing.md index 7fcc6c39..13c9df3f 100644 --- a/devdocs/pricing.md +++ b/devdocs/pricing.md @@ -139,7 +139,7 @@ TWO types makes the most sense after considering options: - One time fee, user can use indefinitely - self installed, hosted and maintained by customer - least profitable for us long term if they don't buy a maint. subscription -- Without maintenance subscription, eligable for Minor updates only to fix bugs no new features so in other words they buy 8.0.2 they can upgrade to any 8.0.X version release, but not 8.1 as it will be new features added that don't break backward compatibility +- Without maintenance subscription, eligable for Minor updates only to fix bugs no new features so in other words they buy 8.0.3 they can upgrade to any 8.0.X version release, but not 8.1 as it will be new features added that don't break backward compatibility - one-time payment, along with the option of a yearly maintenance fee. - This is basically our current model but we allow upgrades for subscribers - **HAS CODE IMPLICATIONS** upgrades need to check if allowed based on version number if no maintenance subscription _not_ on date of build. diff --git a/devdocs/todo.txt b/devdocs/todo.txt index f56f128c..52138f2e 100644 --- a/devdocs/todo.txt +++ b/devdocs/todo.txt @@ -8,9 +8,17 @@ without hassle RESEARCH: sendgrid / email system can we have a domain just for our notifications for those that don't use their own domain and use for all users (but NOT tied to AyaNova.com) https://linuxhandbook.com/set-up-discourse-digital-ocean/ has an example of discourse with Mailgun freen email ssytem and a domain +(NOT MAILCHIMP AFTER HACK that affected digitalocean they sound like dicks) TEST: cheapest storage for attachments possible, test out creating a new droplet with block storage to hold the attachment files to see if it's possible, how it's done and mapped etc + +todo: implement and test now system to prevent download subscription instance database and just use locally, i.e. check for special file or whatever system we implement + check for subscription key file presence and signature inside to be checked in case they parse the code and put teh file by that name needs to be not enough but signed inside too + +todo: can user use erase key flag to get trial and then use trial for 5 days and just keep on doing that or isn't there a check to erase db first?? + needs some way to ensure this doesn't happen, maybe a user check or something or some sign it's not eval?? + todo: maintenance plan agreement? SB something in the license docs I guess since it differs, also license text will need to be chagned as it is on assumption of built in maint before Here is autodesks maintenance plan agreement page: https://www.autodesk.com/company/legal-notices-trademarks/autodesk-terms-and-conditions/eng_autodeskmaintenancesubscriptiontermsandconditions @@ -25,7 +33,7 @@ todo: on ops server info page show main disk usage of db, attachments free memor todo: v8migrate Contracts in v7 were allowed to have no name, add code to invent a name on migration so it doesn't bomb -todo: QBI don't check build date against expiry date if it's a trial, i.e. they can upgrade a trial all they want as long as it's not expired key +todo: license agreement changes for perpetual, since maint is no longer included or maybe just add 30 day bit and bit about optional maintenance agreement and keep in one place todo: License agreement changes for SAAS customers, this is huge and I hadn't thought of it before, wording is very different in this case, fuck, need to wing it I guess https://flgpartners.com/saas-pivots-transitions-perpetual-to-subscription-saas-models/ @@ -39,9 +47,12 @@ todo: SAAS gaming, once have idea of plans and add-ons, need to test it out on s todo: ROCKFISH different license key signature if it's a SAAS license this solves a lot of problems, effectively it's unlicensed if they move their data to their own hardware without a key requires that AyaNova have different internal key to check, maybe it's actually a build switch for that since only we will be running our SAAS version. + dual signatures doesnt' work becuase it would mean ayanova could just work anyway since it can check either, need something else. + build switch would work but it means a whole separate build every tiem which is fucky, but maybe necessary. todo: ROCKFISH can't make a trial key for users in the UI, only when it's requested from ayanova. I'm really not sure if this is an issue or not but putting it on the list in case + add as a feature just in case todo: DOCS - remove all mention of digitalocean from the install and other docs since we're going to be using them for SAAS we don't want to make it simple for people to host themselves, just say Linux and leave it at that. @@ -1237,10 +1248,6 @@ https://www.ayanova.com/download/next/ayanova-linux-x64-server.zip https://www.ayanova.com/download/next/ayanova-windows-x64-lan-setup.exe Current v8 docs home: https://www.ayanova.com/docs/next -BUILD 8.0.2 rc2 CHANGES OF NOTE - -Added integration back end feature for integration of external applications with AyaNova 8 -Added front end administrative UI for viewing and controlling integrated applications and their logs -Fixed potential lockout situation in AyaNova front end with force change known password code -Expanded roles allowed to fetch license to support integration of external applications +BUILD 8.0.3 CHANGES OF NOTE +Allow negative quantities on most work order subitems diff --git a/dist/install/windows/x64/lan.iss b/dist/install/windows/x64/lan.iss index abf03b21..8159f632 100644 --- a/dist/install/windows/x64/lan.iss +++ b/dist/install/windows/x64/lan.iss @@ -1,7 +1,7 @@ ; LAN install for internal network use only #define MyAppName "AyaNova server" -#define MyAppVersion "8.0.2" +#define MyAppVersion "8.0.3" #define MyAppPublisher "Ground Zero Tech-Works, Inc." #define MyAppURL "https://ayanova.com/" #define MyAppLauncherExeName "ayanova-launcher.exe" diff --git a/dist/install/windows/x64/standalone.iss b/dist/install/windows/x64/standalone.iss index 672be039..0c8ac5fd 100644 --- a/dist/install/windows/x64/standalone.iss +++ b/dist/install/windows/x64/standalone.iss @@ -3,7 +3,7 @@ ; external to lan requires different config #define MyAppName "AyaNova" -#define MyAppVersion "8.0.2" +#define MyAppVersion "8.0.3" #define MyAppPublisher "Ground Zero Tech-Works, Inc." #define MyAppURL "https://ayanova.com/" #define MyAppLauncherExeName "ayanova-launcher.exe" diff --git a/docs/8.0/ayanova/docs/adm-license.md b/docs/8.0/ayanova/docs/adm-license.md index 8c4f6bee..28b1ada0 100644 --- a/docs/8.0/ayanova/docs/adm-license.md +++ b/docs/8.0/ayanova/docs/adm-license.md @@ -4,7 +4,6 @@ The license form is used to view the AyaNova license and perform license related The AyaNova license is stored inside the database so as long as you have a backup of the database you have the license backed up as well. -## What is the difference between a license and a support and updates subscription? ## Trying out AyaNova @@ -100,18 +99,20 @@ If AyaNova is licensed for temporary time periods (e.g. month to month as a host In the case of regular non temporary licenses this will not display. -#### Support and updates expiration date +#### Maintenance plan expiration date -This is the date that the current support and updates subscription will [expire](#maintenance-expired-message). +This is the date that the current Maintenance plan for support and updates will [expire](#maintenance-expired-message). -After this time AyaNova will not be updateable and technical support will no longer be available if required. +After this time AyaNova will not be updateable and technical support will no longer be available if required without the purchase of a Maintenance plan. #### Licensed options -This section shows the options selected for the current license including service technician user count and other options such as accounting integration. +This section shows the options selected for the current license including service technician user count and other optional additions. ##### Service technician Scheduleable users and licensing +**Perpetual type licenses only** + In order to provide fair pricing that scales with the size of a company AyaNova is licensed by service technician (scheduleable user) count. Service technician and sub-contractor type Users also known as "scheduleable users" in AyaNova are Users that have their "User Type" field set to "Service user" or "Sub-contractor user" in their their [User record ](adm-users.md). Users set to this type are scheduleable and trackable for service in AyaNova and selectable on work orders, quotes and preventive maintenance orders. @@ -161,6 +162,8 @@ These items are kept as this feature is typically used when people are evaluatin ## Downgrading a license +**Perpetual type licenses** + If a replacement license is installed that has fewer service technicians that the prior license and the administrator has not disabled the extra service techncians first, AyaNova will automatically disable any excess service techs / scheduleable Users by setting their `Active` property to false in order to remain with the purchased license count. AyaNova tries to do this in the least disruptive way possible by favoring disabling in this order: @@ -175,9 +178,20 @@ We recommend the administrator disable the excess service techs before downgradi If a tech was automatically disabled to remain within the licensed limit that shouldn't be, you can set another tech inactive and then set the de-activated tech back to active so they can continue working. +**Subscription licenses** + +AyaNova will autoamtically deactivate excess Users of any kind preferring Users who have not logged in ever or failing that the longest time since login. + +We recommend the administrator disable the excess Users before downgrading the license to avoid any potential disruption. + +If a User was automatically disabled to remain within the licensed limit that shouldn't be, you can set another User inactive and then set the de-activated User back to active so they can continue working. + + ## User count exceeded -If you receive an error message stating that the Server is locked due to exceeding licensed active scheduleable User limit this means that AyaNova has found there to be more Active Scheduleable Users than the license permits. +If you receive an error message stating that the Server is locked due to exceeding licensed limit this means that AyaNova has found there to be more Active Users than the license permits. + +In the case of Perpetual licenses this is Scheduleable Users (Service Technicians) and for Subscription hosted licenses this is all Users. This is typically a sign that the database has been directly edited outside of AyaNova and needs to be fixed by restoring from backup made _before_ the editing took place or, if it is absolutely _certain_ this was the only change made, setting Scheduleable User's to Active=false to match the _Licensed_ Active Schedulable user count. @@ -191,30 +205,25 @@ Your support agreement does _not_ cover damage caused by directly editing the da ![maintenance expired](img/adm-license-maintenance-expired.png) -This message indicates that your support and updates subscription for AyaNova has expired and you may continue to use AyaNova but you are no longer eligable for technical support or updates to AyaNova. +This message indicates that your Maintenance plan for AyaNova has expired and you may continue to use AyaNova but you are no longer eligable for technical support or updates to AyaNova. ### Can I still use AyaNova? -Yes. Your AyaNova license is separate from the support and updates subscription and is still in effect unless it is a temporary license that has expired. +Yes. Your AyaNova license is separate from the Maintenance plan and is still in effect unless it is a temporary license that has expired. -You will not be able to receive email support nor update with an expired subscription. +You will not be able to receive technical support nor update with an expired subscription. ### What if I need technical support? -You will need to [purchase](https://ayanova.com/r/pricing.htm) a support and updates subscription to receive technical support. +You will need to [purchase](https://ayanova.com/r/pricing.htm) a Maintenance plan to receive technical support. ### What if I need to update AyaNova? -You will need to [purchase](https://ayanova.com/r/pricing.htm) a support and updates subscription to update AyaNova. +You will need to [purchase](https://ayanova.com/r/pricing.htm) a Maintenance plan to update AyaNova. ### What happens if I update AyaNova with an expired subscription? -AyaNova will not operate if it was released after your support and updates subscription expired and no one will be able to access AyaNova except the Super User account for the purposes of installing a license only. +AyaNova will not operate if it was released after your Maintenance plan expired and no one will be able to access AyaNova except the Super User account for the purposes of installing a license only. -You will need to [purchase](https://ayanova.com/r/pricing.htm) a support and updates subscription to continue working or downgrade back to the version you were using prior to upgrading. +You will need to [purchase](https://ayanova.com/r/pricing.htm) a Maintenance plan to continue working or downgrade back to the version you were using prior to upgrading. -### Will I get a discount if I renew an expired subscription? - -If you're subscription has expired within 2 weeks of the purchasing date, you are eligable for the same discounted price as an ongoing [subscription renewal](https://ayanova.com/r/pricing.htm). - -If more than two weeks have passed since the subscription expired, the subscription will be the [full price](https://ayanova.com/r/pricing.htm). diff --git a/docs/8.0/ayanova/docs/ops-upgrade-linux-desktop.md b/docs/8.0/ayanova/docs/ops-upgrade-linux-desktop.md index 5174efa6..acfd80f7 100644 --- a/docs/8.0/ayanova/docs/ops-upgrade-linux-desktop.md +++ b/docs/8.0/ayanova/docs/ops-upgrade-linux-desktop.md @@ -4,9 +4,9 @@ The linux desktop upgrade process involves replacing the AyaNova program files w These instructions assume the original installation steps were followed without changes, if you had to make changes adjust accordingly. -## Expired support and updates subscription +### Expired Maintenance plan -If you do not have an active support and updates subscription you will [not be able to update](adm-license.md#maintenance-expired-message). +If you do not have an active Maintenance plan you will [not be able to update](adm-license.md#maintenance-expired-message). ### 1\. Backup diff --git a/docs/8.0/ayanova/docs/ops-upgrade-linux-server.md b/docs/8.0/ayanova/docs/ops-upgrade-linux-server.md index 04c506d5..5697f33b 100644 --- a/docs/8.0/ayanova/docs/ops-upgrade-linux-server.md +++ b/docs/8.0/ayanova/docs/ops-upgrade-linux-server.md @@ -4,9 +4,9 @@ The linux server upgrade process involves replacing the AyaNova program files wi These instructions assume the original installation steps were followed without changes, if you had to make changes adjust accordingly. -## Expired support and updates subscription +### Expired Maintenance plan -If you do not have an active support and updates subscription you will [not be able to update](adm-license.md#maintenance-expired-message). +If you do not have an active Maintenance plan you will [not be able to update](adm-license.md#maintenance-expired-message). ### 1\. Backup diff --git a/docs/8.0/ayanova/docs/ops-upgrade-windows-iis.md b/docs/8.0/ayanova/docs/ops-upgrade-windows-iis.md index f9f90710..99e8f77e 100644 --- a/docs/8.0/ayanova/docs/ops-upgrade-windows-iis.md +++ b/docs/8.0/ayanova/docs/ops-upgrade-windows-iis.md @@ -2,9 +2,9 @@ These instructions assume the original installation steps were followed without changes, if you had to make changes adjust accordingly. -## Expired support and updates subscription +### Expired Maintenance plan -If you do not have an active support and updates subscription you will [not be able to update](adm-license.md#maintenance-expired-message). +If you do not have an active Maintenance plan you will [not be able to update](adm-license.md#maintenance-expired-message). ### 1\. Backup diff --git a/docs/8.0/ayanova/docs/ops-upgrade-windows-lan.md b/docs/8.0/ayanova/docs/ops-upgrade-windows-lan.md index 082fa16e..cd29bf5a 100644 --- a/docs/8.0/ayanova/docs/ops-upgrade-windows-lan.md +++ b/docs/8.0/ayanova/docs/ops-upgrade-windows-lan.md @@ -2,9 +2,9 @@ These instructions assume the original installation steps were followed without changes, if you had to make changes adjust accordingly. -## Expired support and updates subscription +### Expired Maintenance plan -If you do not have an active support and updates subscription you will [not be able to update](adm-license.md#maintenance-expired-message). +If you do not have an active Maintenance plan you will [not be able to update](adm-license.md#maintenance-expired-message). ### 1\. Backup diff --git a/docs/8.0/ayanova/docs/ops-upgrade-windows-single.md b/docs/8.0/ayanova/docs/ops-upgrade-windows-single.md index cd7c7991..b0a69994 100644 --- a/docs/8.0/ayanova/docs/ops-upgrade-windows-single.md +++ b/docs/8.0/ayanova/docs/ops-upgrade-windows-single.md @@ -2,9 +2,9 @@ These instructions assume the original installation steps were followed without changes, if you had to make changes adjust accordingly. -## Expired support and updates subscription +### Expired Maintenance plan -If you do not have an active support and updates subscription you will [not be able to update](adm-license.md#maintenance-expired-message). +If you do not have an active Maintenance plan you will [not be able to update](adm-license.md#maintenance-expired-message). ### 1\. Backup diff --git a/docs/8.0/ayanova/docs/ops-upgrade.md b/docs/8.0/ayanova/docs/ops-upgrade.md index 658731f2..6bcd0efc 100644 --- a/docs/8.0/ayanova/docs/ops-upgrade.md +++ b/docs/8.0/ayanova/docs/ops-upgrade.md @@ -1,8 +1,8 @@ # AyaNova upgrade -AyaNova updates are available to users with an active support and updates subscription. +AyaNova updates are available to users with an active Maintenance plan. -If you do not have an active support and updates subscription you will [not be able to update](adm-license.md#maintenance-expired-message). +If you do not have an active Maintenance plan you will [not be able to update](adm-license.md#maintenance-expired-message). Choose your platform for update instructions: diff --git a/docs/8.0/ayanova/mkdocs.yml b/docs/8.0/ayanova/mkdocs.yml index 185c3f56..fb242089 100644 --- a/docs/8.0/ayanova/mkdocs.yml +++ b/docs/8.0/ayanova/mkdocs.yml @@ -7,7 +7,7 @@ theme: site_name: AyaNova manual site_dir: '../../../server/AyaNova/wwwroot/docs' strict: true -copyright: Copyright © 2022 Ground Zero Tech-Works Inc. REV-2022-08-12 +copyright: Copyright © 2022 Ground Zero Tech-Works Inc. REV-2022-08-15 extra: generator: false # Extensions diff --git a/server/AyaNova/AyaNova.csproj b/server/AyaNova/AyaNova.csproj index 399697c6..99506220 100644 --- a/server/AyaNova/AyaNova.csproj +++ b/server/AyaNova/AyaNova.csproj @@ -4,8 +4,8 @@ true - 8.0.2 - 8.0.2.0 + 8.0.3 + 8.0.3.0 ayanova.ico bin\$(Configuration)\$(TargetFramework)\$(AssemblyName).xml 1591 diff --git a/server/AyaNova/biz/PMBiz.cs b/server/AyaNova/biz/PMBiz.cs index d5cdf4c1..7e0d2ad5 100644 --- a/server/AyaNova/biz/PMBiz.cs +++ b/server/AyaNova/biz/PMBiz.cs @@ -2228,11 +2228,12 @@ namespace AyaNova.Biz if (proposedObj.ServiceStartDate > proposedObj.ServiceStopDate) AddError(ApiErrorCode.VALIDATION_STARTDATE_AFTER_ENDDATE, "ServiceStartDate"); - if (proposedObj.ServiceRateQuantity < 0)//negative quantities are not allowed - AddError(ApiErrorCode.VALIDATION_INVALID_VALUE, "ServiceRateQuantity"); - - if (proposedObj.NoChargeQuantity < 0)//negative quantities are not allowed - AddError(ApiErrorCode.VALIDATION_INVALID_VALUE, "NoChargeQuantity"); + //case 4171 removed + // if (proposedObj.ServiceRateQuantity < 0)//negative quantities are not allowed + // AddError(ApiErrorCode.VALIDATION_INVALID_VALUE, "ServiceRateQuantity"); + //case 4171 removed + // if (proposedObj.NoChargeQuantity < 0)//negative quantities are not allowed + // AddError(ApiErrorCode.VALIDATION_INVALID_VALUE, "NoChargeQuantity"); //Any form customizations to validate? var FormCustomization = await ct.FormCustom.AsNoTracking().SingleOrDefaultAsync(z => z.FormKey == AyaType.PM.ToString()); @@ -2626,8 +2627,9 @@ namespace AyaNova.Biz if (proposedObj.LoanUnitId < 1 || !await ct.LoanUnit.AnyAsync(x => x.Id == proposedObj.LoanUnitId)) AddError(ApiErrorCode.VALIDATION_INVALID_VALUE, "LoanUnitId"); - if (proposedObj.Quantity < 0)//negative quantities are not allowed - AddError(ApiErrorCode.VALIDATION_INVALID_VALUE, "Quantity"); + //case 4171 removed + // if (proposedObj.Quantity < 0)//negative quantities are not allowed + // AddError(ApiErrorCode.VALIDATION_INVALID_VALUE, "Quantity"); //Any form customizations to validate? @@ -3653,9 +3655,9 @@ namespace AyaNova.Biz return; } - - if (proposedObj.EstimatedQuantity < 0)//negative quantities are not allowed - AddError(ApiErrorCode.VALIDATION_INVALID_VALUE, "EstimatedQuantity"); + //case 4171 removed + // if (proposedObj.EstimatedQuantity < 0)//negative quantities are not allowed + // AddError(ApiErrorCode.VALIDATION_INVALID_VALUE, "EstimatedQuantity"); //Start date AND end date must both be null or both contain values @@ -4319,11 +4321,12 @@ namespace AyaNova.Biz return; } - if (proposedObj.TravelRateQuantity < 0)//negative quantities are not allowed - AddError(ApiErrorCode.VALIDATION_INVALID_VALUE, "TravelRateQuantity"); + //case 4171 removed + // if (proposedObj.TravelRateQuantity < 0)//negative quantities are not allowed + // AddError(ApiErrorCode.VALIDATION_INVALID_VALUE, "TravelRateQuantity"); - if (proposedObj.NoChargeQuantity < 0)//negative quantities are not allowed - AddError(ApiErrorCode.VALIDATION_INVALID_VALUE, "NoChargeQuantity"); + // if (proposedObj.NoChargeQuantity < 0)//negative quantities are not allowed + // AddError(ApiErrorCode.VALIDATION_INVALID_VALUE, "NoChargeQuantity"); //Any form customizations to validate? var FormCustomization = await ct.FormCustom.AsNoTracking().SingleOrDefaultAsync(z => z.FormKey == AyaType.PM.ToString()); diff --git a/server/AyaNova/biz/QuoteBiz.cs b/server/AyaNova/biz/QuoteBiz.cs index 659b6a72..a00a846d 100644 --- a/server/AyaNova/biz/QuoteBiz.cs +++ b/server/AyaNova/biz/QuoteBiz.cs @@ -1111,7 +1111,7 @@ namespace AyaNova.Biz var newStatusInfo = await ct.QuoteStatus.AsNoTracking().FirstOrDefaultAsync(x => x.Id == newObject.QuoteStatusId); quote.LastStatusId = newObject.QuoteStatusId; await ct.SaveChangesAsync(); - newObject.NewQuoteConcurrency=quote.Concurrency; + newObject.NewQuoteConcurrency = quote.Concurrency; await EventLogProcessor.LogEventToDatabaseAsync(new Event(UserId, newObject.Id, AyaType.QuoteStatus, AyaEvent.Created), ct); await StateHandlePotentialNotificationEvent(AyaEvent.Created, newObject); @@ -1294,7 +1294,7 @@ namespace AyaNova.Biz //Object tags must match and Customer tags must match if (NotifyEventHelper.ObjectHasAllSubscriptionTags(QuoteInfo.Tags, sub.Tags) && NotifyEventHelper.ObjectHasAllSubscriptionTags(custInfo.Tags, sub.CustomerTags)) { - + CustomerNotifyEvent n = new CustomerNotifyEvent() { EventType = NotifyEventType.QuoteStatusChange, @@ -2461,11 +2461,12 @@ namespace AyaNova.Biz if (proposedObj.ServiceStartDate > proposedObj.ServiceStopDate) AddError(ApiErrorCode.VALIDATION_STARTDATE_AFTER_ENDDATE, "ServiceStartDate"); - if (proposedObj.ServiceRateQuantity < 0)//negative quantities are not allowed - AddError(ApiErrorCode.VALIDATION_INVALID_VALUE, "ServiceRateQuantity"); + //case 4171 removed + // if (proposedObj.ServiceRateQuantity < 0)//negative quantities are not allowed + // AddError(ApiErrorCode.VALIDATION_INVALID_VALUE, "ServiceRateQuantity"); - if (proposedObj.NoChargeQuantity < 0)//negative quantities are not allowed - AddError(ApiErrorCode.VALIDATION_INVALID_VALUE, "NoChargeQuantity"); + // if (proposedObj.NoChargeQuantity < 0)//negative quantities are not allowed + // AddError(ApiErrorCode.VALIDATION_INVALID_VALUE, "NoChargeQuantity"); //Any form customizations to validate? var FormCustomization = await ct.FormCustom.AsNoTracking().SingleOrDefaultAsync(z => z.FormKey == AyaType.Quote.ToString()); @@ -2864,11 +2865,12 @@ namespace AyaNova.Biz } } - if (proposedObj.LoanUnitId < 1 || !await ct.LoanUnit.AnyAsync(x => x.Id == proposedObj.LoanUnitId)) - AddError(ApiErrorCode.VALIDATION_INVALID_VALUE, "LoanUnitId"); + //case 4171 removed + // if (proposedObj.LoanUnitId < 1 || !await ct.LoanUnit.AnyAsync(x => x.Id == proposedObj.LoanUnitId)) + // AddError(ApiErrorCode.VALIDATION_INVALID_VALUE, "LoanUnitId"); - if (proposedObj.Quantity < 0)//negative quantities are not allowed - AddError(ApiErrorCode.VALIDATION_INVALID_VALUE, "Quantity"); + // if (proposedObj.Quantity < 0)//negative quantities are not allowed + // AddError(ApiErrorCode.VALIDATION_INVALID_VALUE, "Quantity"); //Any form customizations to validate? @@ -3679,8 +3681,9 @@ namespace AyaNova.Biz return; } - if (proposedObj.Quantity < 0)//negative quantities are not allowed - AddError(ApiErrorCode.VALIDATION_INVALID_VALUE, "Quantity"); + //case 4171 removed + // if (proposedObj.Quantity < 0)//negative quantities are not allowed + // AddError(ApiErrorCode.VALIDATION_INVALID_VALUE, "Quantity"); //Any form customizations to validate? var FormCustomization = await ct.FormCustom.AsNoTracking().SingleOrDefaultAsync(z => z.FormKey == AyaType.Quote.ToString()); @@ -3927,8 +3930,9 @@ namespace AyaNova.Biz } } - if (proposedObj.EstimatedQuantity < 0)//negative quantities are not allowed - AddError(ApiErrorCode.VALIDATION_INVALID_VALUE, "EstimatedQuantity"); + //case 4171 removed + // if (proposedObj.EstimatedQuantity < 0)//negative quantities are not allowed + // AddError(ApiErrorCode.VALIDATION_INVALID_VALUE, "EstimatedQuantity"); //Start date AND end date must both be null or both contain values @@ -4614,11 +4618,12 @@ namespace AyaNova.Biz return; } - if (proposedObj.TravelRateQuantity < 0)//negative quantities are not allowed - AddError(ApiErrorCode.VALIDATION_INVALID_VALUE, "TravelRateQuantity"); + //case 4171 removed + // if (proposedObj.TravelRateQuantity < 0)//negative quantities are not allowed + // AddError(ApiErrorCode.VALIDATION_INVALID_VALUE, "TravelRateQuantity"); - if (proposedObj.NoChargeQuantity < 0)//negative quantities are not allowed - AddError(ApiErrorCode.VALIDATION_INVALID_VALUE, "NoChargeQuantity"); + // if (proposedObj.NoChargeQuantity < 0)//negative quantities are not allowed + // AddError(ApiErrorCode.VALIDATION_INVALID_VALUE, "NoChargeQuantity"); //Any form customizations to validate? var FormCustomization = await ct.FormCustom.AsNoTracking().SingleOrDefaultAsync(z => z.FormKey == AyaType.Quote.ToString()); diff --git a/server/AyaNova/biz/WorkOrderBiz.cs b/server/AyaNova/biz/WorkOrderBiz.cs index fd2daf0b..c0f9e61e 100644 --- a/server/AyaNova/biz/WorkOrderBiz.cs +++ b/server/AyaNova/biz/WorkOrderBiz.cs @@ -1687,8 +1687,8 @@ namespace AyaNova.Biz return null; else { - if(newObject.UserId==0) - newObject.UserId=UserId; + if (newObject.UserId == 0) + newObject.UserId = UserId; await ct.WorkOrderState.AddAsync(newObject); var wo = await ct.WorkOrder.FirstOrDefaultAsync(x => x.Id == newObject.WorkOrderId); @@ -3261,12 +3261,13 @@ namespace AyaNova.Biz if (proposedObj.ServiceStartDate > proposedObj.ServiceStopDate) AddError(ApiErrorCode.VALIDATION_STARTDATE_AFTER_ENDDATE, "ServiceStartDate"); - + //case 4171 removed // if (proposedObj.ServiceRateQuantity < 0)//negative quantities are not allowed // AddError(ApiErrorCode.VALIDATION_INVALID_VALUE, "ServiceRateQuantity"); - if (proposedObj.NoChargeQuantity < 0)//negative quantities are not allowed - AddError(ApiErrorCode.VALIDATION_INVALID_VALUE, "NoChargeQuantity"); + //case 4171 removed + // if (proposedObj.NoChargeQuantity < 0)//negative quantities are not allowed + // AddError(ApiErrorCode.VALIDATION_INVALID_VALUE, "NoChargeQuantity"); //Any form customizations to validate? var FormCustomization = await ct.FormCustom.AsNoTracking().SingleOrDefaultAsync(z => z.FormKey == AyaType.WorkOrder.ToString());//all workorder sub items use the workorder key for customization @@ -3703,11 +3704,12 @@ namespace AyaNova.Biz } } - if (proposedObj.LoanUnitId < 1 || !await ct.LoanUnit.AnyAsync(x => x.Id == proposedObj.LoanUnitId)) - AddError(ApiErrorCode.VALIDATION_INVALID_VALUE, "LoanUnitId"); + //case 4171 removed + // if (proposedObj.LoanUnitId < 1 || !await ct.LoanUnit.AnyAsync(x => x.Id == proposedObj.LoanUnitId)) + // AddError(ApiErrorCode.VALIDATION_INVALID_VALUE, "LoanUnitId"); - if (proposedObj.Quantity < 0)//negative quantities are not allowed - AddError(ApiErrorCode.VALIDATION_INVALID_VALUE, "Quantity"); + // if (proposedObj.Quantity < 0)//negative quantities are not allowed + // AddError(ApiErrorCode.VALIDATION_INVALID_VALUE, "Quantity"); //Any form customizations to validate? @@ -5605,8 +5607,9 @@ namespace AyaNova.Biz } } - if (proposedObj.EstimatedQuantity < 0)//negative quantities are not allowed - AddError(ApiErrorCode.VALIDATION_INVALID_VALUE, "EstimatedQuantity"); + //case 4171 removed + // if (proposedObj.EstimatedQuantity < 0)//negative quantities are not allowed + // AddError(ApiErrorCode.VALIDATION_INVALID_VALUE, "EstimatedQuantity"); //Start date AND end date must both be null or both contain values @@ -6422,11 +6425,12 @@ namespace AyaNova.Biz return; } - if (proposedObj.TravelRateQuantity < 0)//negative quantities are not allowed - AddError(ApiErrorCode.VALIDATION_INVALID_VALUE, "TravelRateQuantity"); + //case 4171 removed + // if (proposedObj.TravelRateQuantity < 0)//negative quantities are not allowed + // AddError(ApiErrorCode.VALIDATION_INVALID_VALUE, "TravelRateQuantity"); - if (proposedObj.NoChargeQuantity < 0)//negative quantities are not allowed - AddError(ApiErrorCode.VALIDATION_INVALID_VALUE, "NoChargeQuantity"); + // if (proposedObj.NoChargeQuantity < 0)//negative quantities are not allowed + // AddError(ApiErrorCode.VALIDATION_INVALID_VALUE, "NoChargeQuantity"); //Any form customizations to validate? var FormCustomization = await ct.FormCustom.AsNoTracking().SingleOrDefaultAsync(z => z.FormKey == AyaType.WorkOrder.ToString());//all workorder sub items use the workorder key for customization @@ -6650,7 +6654,7 @@ namespace AyaNova.Biz //cache it var unitInfo = await ct.Unit.AsNoTracking() .Where(x => x.Id == o.UnitId) - .Select(x => new { x.Serial, x.Description, x.UnitModelId, x.Address, x.City, x.Region, x.Country, x.Latitude, x.Longitude, x.Metered}) + .Select(x => new { x.Serial, x.Description, x.UnitModelId, x.Address, x.City, x.Region, x.Country, x.Latitude, x.Longitude, x.Metered }) .FirstOrDefaultAsync(); vc.Add(unitInfo.Serial, "unitserial", o.UnitId); vc.Add(unitInfo.Description, "unitdesc", o.UnitId); diff --git a/server/AyaNova/resource/en.json b/server/AyaNova/resource/en.json index bdf8f676..24764def 100644 --- a/server/AyaNova/resource/en.json +++ b/server/AyaNova/resource/en.json @@ -537,7 +537,7 @@ "LogFile": "Log file", "Logout": "Log out", "MaintenanceExpired": "Maintenance expired", - "MaintenanceExpiredNote": "The support and updates subscription has now expired\nAyaNova can not be updated and support is no longer available", + "MaintenanceExpiredNote": "The Maintenance plan has now expired\nAyaNova can not be updated and support is no longer available", "MapUrlTemplate": "Map URL template", "MediumLogo": "Medium sized logo", "Memo": "Memo", @@ -1066,7 +1066,7 @@ "StopWords5": "?", "StopWords6": "?", "StopWords7": "?", - "SupportedUntil": "Support and updates expiration date", + "SupportedUntil": "Maintenance plan expiration date", "Table": "Table", "Tag": "Tag", "TaggedWith": "Tagged with", diff --git a/server/AyaNova/util/AyaNovaVersion.cs b/server/AyaNova/util/AyaNovaVersion.cs index dfccf29d..1978c5e3 100644 --- a/server/AyaNova/util/AyaNovaVersion.cs +++ b/server/AyaNova/util/AyaNovaVersion.cs @@ -5,7 +5,7 @@ namespace AyaNova.Util /// internal static class AyaNovaVersion { - public const string VersionString = "8.0.2"; + public const string VersionString = "8.0.3"; public const string FullNameAndVersion = "AyaNova server " + VersionString; public const string CurrentApiVersion="v8"; }//eoc diff --git a/server/AyaNova/util/License.cs b/server/AyaNova/util/License.cs index dbd0b0f8..fa14d6ba 100644 --- a/server/AyaNova/util/License.cs +++ b/server/AyaNova/util/License.cs @@ -59,11 +59,7 @@ namespace AyaNova.Core private const string TRIAL_FEATURE_NAME = "TrialMode"; //This feature name means it's a SAAS or rental mode key for month to month hosted service - //effectively what it does now 2022-08-04 17:26:20 is nothing at all - //license expiry is still controlled by checking Temporary key / expires in rockfish v8 license generator page - //which in turn causes expiry date to be displayed in the license UI - //I think this may be redundant but I'll keep it for now maybe it might help in future to offer a rental payment UI inside AyaNova or something - private const string RENTAL_FEATURE_NAME = "ServiceMode"; + private const string RENTAL_FEATURE_NAME = "Subscription"; //Trial key magic number for development and testing, all other guids will be fully licensed