Closed cdhassell closed 2 years ago
Follow up: The fatal error refers to a mysql error #1062, Duplicate entry 'civicrm_contribution-6851-6851-14-9' for key 'UI_line_item_value'. That key is defined as:
ADD UNIQUE KEY
UI_line_item_value
(entity_table
,entity_id
,contribution_id
,price_field_value_id
,price_field_id
),
So the key is a unique combination of the table name, entity ID, contribution ID, etc. But there is no such contribution ID as 6851, not in the civicrm_contribution table nor in civicrm_line_item. So why is this a duplicate? I took the step of optimizing the table in case some sort of inconsistency has crept into the index. But there was no change in behavior.
Further on this:
It appears that this error occurs whenever there is more than one kind of product in the Woocommerce cart. For example, a user buys 2 youth tickets and 3 adult tickets. This produces one row in the civicrm_line_item table for the youth tickets, and one row for the adult tickets. Both rows are tied to the same WC order ID, and therefore the same contribution_id. All of the indexed fields in the UI_line_item_value index will be identical in this case. Since the index is set for "UNIQUE" the insert of the second row will fail with a duplicate error.
When I alter the UI_line_item_value index to remove "UNIQUE" then it works. Obviously it is not a good solution to change the CiviCRM database schema! So it seems like the data from woocommerce_civicrm plugin are not formatted in a way that fits with the existing schema if there are multiple product types in the WC cart.
Not sure what to do at this point but I would like to hear from others if the above diagnosis makes sense or if there is another solution.
@cdhassell great debugging and yes I think you are correct.
A few different ways to solve this issue:
Have raised a PR to alter the CiviCRM database schema, see https://github.com/civicrm/civicrm-core/pull/22200
You should not be trying to have two line items for the same price_set_field_id and price_set_field_value_id. Instead of multiple line items for the same field/option you should increase the qty.
Probably what you really want is to have a price set with multiple fields if it is appropriate to have multiple line items. The WooCommerce integration should be assisting and requiring this. Happy to have a call to discuss if you want, @agileware-justin .
@JoeMurray we went with option 3 as that was the easiest route. In doing so, it makes no sense from what we could see to have an index on those fields. Why would that be there?
Did you find any other possible solutions, different to the 3 outlined above?
The supported approach is to create a distinct price field and/or price field option if there are to be more than one line item. I think that would correspond to 2 above.
@JoeMurray Feel free to open a PR for review
An advantage to doing it the supported way is then the financial information can be different for the different line items. For example, Donation and Membership could have different financial types in the price set configuration, leading to correct recording of different financial accounts in the civicrm_financial_item table.
@JoeMurray seems to be doing the individual financial types just fine.
@agileware-justin have you applied the core patch in your CiviCRM setup to remove the line-item index? If yes, then it will allow recording items with the same/different financial types, although the unique index (UI) is on [entity-table,entity_id,contribution_id,price_field,price_field_value_id]. In this case, with the UI in place, it won't allow recording those 4 line-items of respective financial type as their priceField and priceFieldValue ID is the same - 1.
Extending Joe's comment above, I would say maybe we should have an additional setting on the WooCommerce Product Edit page against CiviCRM setting, where other than Financial Type and Membership type, we can have Price Field option to choose from? Like:
And maybe add a validation rule that will prevent more than one product to have a single price field option? If nothing selected then it will consider the default core price field option - 1
@monishdeb why is there an index on those fields? Just to enforce uniqueness? Or some other practical reason?
The index is to ensure that there is a separate line item for each price field / price field option combination.
@JoeMurray @monishdeb thanks for the comments.
Consider this use case. There is an existing on-line shop, it has ~45,000 products in the catalog. CiviCRM is connected to the store to track contact details, purchases and send newsletters.
By modifying the table schema, removing the unique index on these fields; an order is able to be recorded in CiviCRM as a Contribution and all items in the order recorded as Line Items in the Contribution.
People placing orders using this on-line store can purchase anything from 1 item to 100 items or the entire catalog if they have the time and patience to click Add to Cart that many times. The sky is the limit.
Using this example above, I am not sure if what you are proposing @JoeMurray would then require:
Ideally, whatever the solution. It needs to:
Good discussion.
Interesting discussion folks... I don't have any answers to the set up that @agileware-justin describes (wow, that's a lot of products!) except to say that Integrate CiviCRM with WooCommerce has more than 100 hours of further development beyond what this plugin offers - including assigning a "Price Field Value" to Products... which solves the problem identified in this issue.
My suggestion for the scalability issue would be to create some kind of AJAX-driven dashlet on the Integrate CiviCRM with WooCommerce settings page that iterates through the Woo Products and updates them accordingly.
more than 100 hours of further development
Indeed I reckon probably a great deal more time than that... Integrate CiviCRM with WooCommerce fixes every bug I could find in this plugin, adds support for WooCommerce Products that create Participants in CiviCRM, adds deduping and assigning Contact Sub-types to new Customers and much more. It's also just about ready to submit to the WordPress Plugin Directory. Just so you know.
Indeed I reckon that you are correct. I installed Integrate CiviCRM with WooCommerce instead and the issue is resolved. Thanks for all of your work Christian!
Well that was worth the time commenting on this issue @christianwach - good work :smile:
As some others have reported, the contribution record is not being created, but the sale does show up on the Woocommerce tab in CiviCRM. However this is a bit different. A snippet from the log is copied below - apologies for the length. The way it looks to me is, it hits "Not able to find contribution" but then throws a fatal error because the contribution line item already exists. I don't understand how that can happen.
WP version 5.8.1 CiviCRM 5.41.0 WC 5.8.0 PHP 7.3.22 MySQL 5.7.28
Edit: You can ignore the Debug statements below, I added those to class Woocommerce_CiviCRM_Manager while trying to understand the code.