Magento gives error page instead of product view - database

I have a problem with a Magento webshop (already live -> http://tinyurl.com/bu8vzay).
When you choose a product in a category you will always get an 404 error page.
Do you have any idea?
Things I tried:
updating attributes for all products live (no problems)
clear cache
clearing the indexes
I've been searching for too many hours now. All help is welcome :)

Take look at the Catalog -> Url Rewrtie Section in admin to see if a rewrite is added for that product.
You may also want to check report_event_types table to see if the values below exist, if not then insert them (Always backup your database before making changes):
INSERT INTO `report_event_types` (`event_type_id`, `event_name`, `customer_login`) VALUES
(1, 'catalog_product_view', 1),
(2, 'sendfriend_product', 1),
(3, 'catalog_product_compare_add_product', 1),
(4, 'checkout_cart_add_product', 1),
(5, 'wishlist_add_product', 1),
(6, 'wishlist_share', 1);
Credit to 404 Error on Magento Product Page

Related

IdentityServer4: what is breaking changes from version 2 and/or 3 to version 4?

Where can I find breaking changes list from version 2 and/or 3 to version 4 of IdentityServer4?
I am trying to upgrade a project with IdentityServer4 version 2 to version 4.
I made a migration from 2.2 to 4.1.2 version two years ago and I remember I found some breaking changes. Others were imposed by the upgrade of framework I made (net core 2.1 to 3.1). These are some of the changes related only to IdentityServer4:
Database scheme. If you have data in production you'll need to maintain this data in the migration. Automatic migrations will delete and recreate tables mercilessly. There are table and column renames, new columns, deleted columns, changes in the indexes...
Client Cors Origins validation. There is a new validation to force all Url configured in ClientCorsOrigins to complain with an Origin format. If only one of them does not comply with the format, an exception is thrown. You should review your production values to avoid fails.
// format:
<protocol>://<domain>:<port>
// good examples:
http://localhost:5000
http://example.com
https://anotherdomain.com
http://example.com:1234
// bad examples
http://example.com/
https://example.com/mypath
example.com:1234
Some code changes:
AuthorizationRequest.ClientId -> AuthorizationRequest.Client.ClientId.
ResourceValidationResult groups ApiResources and IdentityResources properties in a common property called Resources.
ValidatedTokenRequest changes his property Scopes to RequestedScopes.
GetAllUserConsentsAsync -> GetAllUserGrantsAsync.
In your UI some ModelViews will need to be updated to the new scheme. If you stared with the QuickStart.UI you can compare with the new version to add the new features.
If you have an admin you'll have to adapt it to the new scheme.
Migrations
I created the migrations automatically and then I edited the migration to reorder and to add manual scripts to save the data (For example, create a table before deleting the old one and move the data).
These are the scripts I had to insert manually for the Up migration.
Reorder the code to create ApiResourceScopes table before deleting column ApiResourceId from ApiScopes table.
Insert Into [ApiResourceScopes] ([ApiResourceId], [Scope]) Select [ApiResourceId], [Name] From [ApiScopes]
As ApiScopes has a new field called Enabled and by default takes 0, you'll want to enable for all of them. Run this script just before create the Enabled column:
Update [ApiScopes] set [Enabled] = 1
ApiSecrets must be moved to the new table ApiResourceSecrets. So you should run this script before delete ApiSecrets:
Insert Into [ApiResourceSecrets] ([Description], [Value], [Expiration], [Type], [ApiResourceId], [Created]) Select [Description], [Value], [Expiration], [Type], [ApiResourceId], GetDate() From [ApiSecrets]
The table IdentityClaims is renamed to IdentityResourceClaims. So you'll need to run this script after crate IdentityResourceClaims and before delete IdentityClaims.
Insert Into [IdentityResourceClaims] ([Type], [IdentityResourceId]) Select [Type], [IdentityResourceId] From [IdentityClaims]
For the Down migration you need to do exactly the reverse:
Restore ApiScopes. Move the data from ApiResourceScopes.ApiResourceId by using in the join the Scope and the Name fields respectively.
Update [ApiScopes] Set [ApiScopes].[ApiResourceId] = apir.[ApiResourceId] from [ApiScopes] apis Inner Join [ApiResourceScopes] apir On apis.[Name] = apir.[Scope]
Restore ApiSecrets. Move the data after create ApiSecrets table and before delete ApiResourceSecrets:
Insert Into [ApiSecrets] ([Description], [Value], [Expiration], [Type], [ApiResourceId]) Select [Description], [Value], [Expiration], [Type], [ApiResourceId] From [ApiResourceSecrets]
Restore IdentityClaims. Move the data after create IdentityClaims and before delete IdentityResourceClaims:
Insert Into [IdentityClaims] ([Type], [IdentityResourceId]) Select [Type], [IdentityResourceId] From [IdentityResourceClaims]

SQL Server & MS Access separate Views for data entry and read only forms?

I'm working on a small company information system using MS Access as the front end and SQL Server 2019 Express as the back end. I am a bit confused about views at the moment.
Here is what I have:
CREATE FUNCTION dbo.DisplayCurrencyFormat
(
#Amount DECIMAL(10,2),
#Currency INT
)
RETURNS NVARCHAR(100)
AS
BEGIN
RETURN
CASE
WHEN #Currency = 1 THEN FORMAT(#Amount, 'C', 'cs-cz')
WHEN #Currency = 2 THEN FORMAT(#Amount, 'C', 'de-ch')
WHEN #Currency = 3 THEN FORMAT(#Amount, 'C', 'en-us')
WHEN #Currency = 4 THEN FORMAT(#Amount, 'C', 'de-de')
END
END
CREATE VIEW v_PurchaseOrderLines
AS
SELECT tbl1PurchaseOrderDetails.PurchaseOrderDetailID,
tbl1PurchaseOrderDetails.PurchaseOrderID,
tbl1Products.ProductName,
tbl1PurchaseOrderDetails.Config,
dbo.DisplayCurrencyFormat(ListPrice,CurrencyID) AS ListPrice,
tbl1PurchaseOrderDetails.Quantity,
FORMAT(tbl1PurchaseOrderDetails.Discount, 'P0') AS Discount,
dbo.DisplayCurrencyFormat(UnitPrice,CurrencyID) AS UnitPrice,
dbo.DisplayCurrencyFormat(UnitPrice*Quantity,CurrencyID) AS TotalPrice,
FORMAT (tbl1PurchaseOrderDetails.VAT, 'P0') AS VAT,
dbo.DisplayCurrencyFormat(UnitPrice*Quantity*(1+VAT),CurrencyID) AS TotalPriceVAT,
tbl1PurchaseOrderDetails.ExpectedDelivery,
tbl1PurchaseOrderDetails.Notes
FROM tbl1PurchaseOrderDetails JOIN tbl1Products ON tbl1PurchaseOrderDetails.ProductID = tbl1Products.ProductID
;
GO
CREATE VIEW v_PurchaseOrderLines_DE
AS
SELECT tbl1PurchaseOrderDetails.PurchaseOrderDetailID,
tbl1PurchaseOrderDetails.PurchaseOrderID,
tbl1PurchaseOrderDetails.ProductID,
tbl1PurchaseOrderDetails.Config,
tbl1PurchaseOrderDetails.Quantity,
tbl1PurchaseOrderDetails.Discount,
tbl1PurchaseOrderDetails.UnitPrice,
tbl1PurchaseOrderDetails.CurrencyID,
tbl1PurchaseOrderDetails.VAT,
tbl1PurchaseOrderDetails.ListPrice,
dbo.DisplayCurrencyFormat(UnitPrice*Quantity,CurrencyID) AS TotalPrice,
dbo.DisplayCurrencyFormat(UnitPrice*Quantity*(1+VAT),CurrencyID) AS TotalPriceVAT,
tbl1PurchaseOrderDetails.ExpectedDelivery,
tbl1PurchaseOrderDetails.Notes
FROM tbl1PurchaseOrderDetails
;
This works quite well but I'm stuck with 2 views. I'm not able to use any view with FORMAT function or joins inside my data entry forms, it will not accept any changes, so the first view is used for the read only form (looking at purchase orders). However I still need to see calculated total prices in real time on my data entry form, that's why I can't feed data directly from the table.
The second view is then used for editing purchase orders.
Is there some workaround how to do all this within a single view, or am I stuck with 2 views for every entity like this one?
Thanks a lot for any tips.
Linked Views with JOINs are editable in Access, if the PK of the underlying table you want to edit is included in the view, and you specify it as PK when linking the view.
Percent formatting can be done in the form.
Currency formatting: you simplify your life and the view by putting the currency symbol into a separate field in view and form. But it is less perfect. :)
It will still depend on your exact requirements if you can get away with a single view for list display vs. editing. It is not always possible.

Spring boot: What is the right way to seed the databse?

I have a Spring Boot application and would like to seed the database the first time the application runs, but not every time the application runs, and then only if the data does not already exist.
My application has a data.sql file and I have it inserting the default users:
-- insert the administrator
INSERT INTO users(id, username, password_hash, email, first_name, last_name) VALUES
(1, 'admin', 'comixed', 'email1#domain.com', 'ComixEd', 'Administrator'),
(2, 'user', 'comixeduser', 'email2#domain.com', 'ComixEd', 'User')
;
-- insert the supported roles
INSERT INTO roles(id, name) VALUES
(1, 'Administrator'),
(2, 'User')
;
-- set the administrator roles
INSERT INTO users_roles(user_id, role_id) VALUES
(1, 1),
(1, 2),
(2, 2)
;
But Spring is obviously trying to run this file every time I start the app. And when it does an exception is raised since the users and roles are already in the database.
What's a better way to do this? And, optionally, what's a way to add new seed data if, in future, new features require new roles, etc.?
Flyway is what you are looking for https://flywaydb.org/
It is a database migration tool that can be used to create and modify databases in a project. It creates its own table in your schema and adds the script name and a checksum value into the tables. During application boot it scans the scripts, checks to see if they're in the table and if the checksums match still. This makes sure the files don't change and everything has been migrated.
You have to configure it in the application.properties file.
Add this line and it should work as you wish:
spring.jpa.hibernate.ddl-auto = update

Trouble creating sql server INSTEAD OF INSERT Trigger

I'm having problems with creating an instead of insert trigger and I was hoping someone could point me what I'm doing wrong.
I have a table with employees id and functionalities id and the functionalities with id 2 or 4 are only available to the employees with id 1 or 4, any other combination is ok.
I created this trigger but no matter what I insert, the result is always a null value in each column.
This is what I have so far:
CREATE TRIGGER TrigInsertEmployee
ON employee_func
INSTEAD OF INSERT AS
BEGIN
DECLARE #idEmp int, #idFunc int
IF(#idFunc IN (2, 4) AND #idEmp NOT IN (1, 4))
BEGIN
REISERROR('Incorrect functionality', 10, 1)
RETURN
END
INSERT INTO employee_func(idEmp, idFunc) VALUES (#idEmp ,#idFunc)
END
Hope someone can help me out!
Thanks
You declared two variables but never set them. When writing an INSERT trigger, SQL exposes a special table called inserted that holds the values the calling process is attempting to insert. See the link below for more information.
http://msdn.microsoft.com/en-us/library/ms191300.aspx
As dazedandconfused mentioned, the INSERTED "special" table is what you need. Here's an example:
CREATE TRIGGER TrigInsertEmployee
ON employee_func
INSTEAD OF INSERT AS
BEGIN
IF(INSERTED.idFunc IN (2, 4) AND INSERTED.idEmp NOT IN (1, 4))
BEGIN
RAISERROR('Incorrect functionality', 10, 1)
RETURN
END
INSERT INTO employee_func(idEmp, idFunc) VALUES (#idEmp ,#idFunc)
END
Also, it may just be a transposition error, but RAISERROR wasn't spelled right in your code.
Finally, for a simple row-based rule like this you could use a CHECK constraint instead:
ALTER TABLE employee_func
ADD CHECK ( NOT(idFunc IN (2, 4) AND idEmp NOT IN (1, 4)) )
I'm just wrapping a "NOT" around your trigger condition here, as the CHECK defines something that's OK whereas your trigger defines something that isn't OK.

Can I change the format of DATA scripted when scripting using SMO?

I would like to use SMO to generate a set of insert statements to copy data between environments. I have this working, but for some reason, datetime fields are formated as hex values that are casted to datetime. This makes the scripts hard to read and impossible to update. Is there a way for me to change this to use a string representation of the date?
Code used to generate:
scripter = New Scripter(<server>)
scripter.Options.ScriptData = True
...
For Each s As String In scripter.EnumScript(list)
writer.WriteLine(FormatScript(s))
Next
I would like to change this...
INSERT [dbo].[dmMessages] ([MessageId], [MessageCd], [MessageDesc], [Status], [EnteredBy], [EnteredDt])
VALUES (1, N'GenericMessages.FieldRequired', N'The {0} field is required.', 1, N'System', CAST(0x00009B4900000000 AS DateTime))
to
INSERT [dbo].[dmMessages] ([MessageId], [MessageCd], [MessageDesc], [Status], [EnteredBy], [EnteredDt])
VALUES (1, N'GenericMessages.FieldRequired', N'The {0} field is required.', 1, N'System', '2009-1-1 13:00:00:000')
One round-about way to get the results you are looking for would be to use BCP to export data and bulk insert to import data as opposed to letting SMO script the data. Read here for more details.

Resources