This file contains technical information most likely to be used by programmers.

-- 1. Cheapest financing rate in product exports --

To add the calculated rate to a product export you may use the following code:

{# Example code for XML Export #}
{% if product.sicoCreditPlusCalculatedRates && product.sicoCreditPlusCalculatedRates|length > 0 %}
    {% for calcRate in product.sicoCreditPlusCalculatedRates %}
    	{# This is pre-filtered to the current exports sales channel #}
        <financing:available>true</financing:available>
        {% if calcRate.sicoAbsoluteMinRateMonths > -1 %}
            <financing:minRateText>Finance from {{ calcRate.sicoAbsoluteMinRateRate|number_format(2,',','.') }} € for {{ calcRate.sicoAbsoluteMinRateMonths }} months.</financing:minRateText>
        {% endif %}
    {% endfor %}
{% else %}
	<financing:available>false</financing:available>
{% endif %}

There are more fields than just sicoAbsoluteMinRateRate and sicoAbsoluteMinRateMonths available. The sicoAbsoluteMinRateInterestRate contains the float value of effective yearly interest percentage.
There are also the following other numbers available, where each block contains one triplet (months, monthly rate, interest percentage) of data.

1. sicoMinMonths, sicoMinMonthsInterestRate and sicoMinMonthsRate: Describe the shortest (by months) possible financing offer. This is just the shortest loan with usually the highest monthly rate.
2. sicoMaxMonths, sicoMaxMonthsInterestRate and sicoMaxMonthsRate: Describe the longest (by months) possible financing offer, which still accounts for the defined minimum Rate (usually 25 Euros). This is the longest loan with usually the lowest monthly rate.
3. sicoAbsoluteMinRateMonths, sicoAbsoluteMinRateRate and sicoAbsoluteMinRateInterestRate: Describe the financing offer with the lowest possible monthly rate, regardless of the months, usually closest to the minimum rate and quite often identical to sicoMaxMonths. This may be identical to the longest loan, but may also be shorter depending on the interest rates defined in the backend.
4. sicoFictionalMinRateMonths, sicoFictionalMinRateRate and sicoFictionalMinRateInterestRate: Describe the financing offer with the lowest impossible monthly rate, regardless of the months and regardless of the minimum Rate (while still above 0 Euros). This is just to show which products may be financed at all. This is mostly internal and serves only as a filter to be able to show "can be financed at all".

When looking at the database, one of the numbers must be bigger than -1 for the line to be found. If all numbers are -1, the product is considered too cheap to finance or is excluded by configuration. Also, if the "sicoCalculationFinished" flag is not set, the product is not yet calculated and thus not yet available for financing. The row also features a sales channel id. Only rows for the specific sales channel are considered.
Based on the filter in the cronjob, each product can only have exactly one or zero lines of financing data per sales channel. The product model is linked by oneToMany towards the calculated rates, so we kept it as a oneToMany field in the export.
In the backend template, if there is a row, the product can be financed. If there are no rows, the product is excluded or not yet calculated.

-- 2. Triggering the "order sent" to CreditPlus --

By default, when you move an order to the status "order sent" (German: "Vollständig ausgeliefert"), the trigger inside the Flow is called.
This is the same as using the "Confirm delivery" (German: "Jetzt Warenversand bestätigen") button on the order detail page. This process triggers the CreditPlus API to proceed with paying out the loan.
You may move the trigger to any other order based trigger or remove it and always trigger it manually by pushing the button. But you have to keep in mind, that the payment from CreditPlus to the shop will only happen once they receive the information. It is also only possible to do this, when the order has the status "Approved and ready for dispatch" (German: "Lieferfreigabe")

-- 3. Working with specific and general product groups for financing --

When creating financing groups, the group may get products assigned. Once the products are assigned this group is not considered a general group anymore.
Products (and baskets) always take their specific groups first and then add general conditions to it. This means that if you have a product defined with 6, 12, 24 months with 3 % interest and a general group with 6, 8, 10, 12, 18, 24, 30, 36 months with 6 % interest, the resulting table will contain the following:
1. 6 months with 3 % interest
2. 8 months with 6 % interest
3. 10 months with 6 % interest
4. 12 months with 3 % interest
5. 18 months with 6 % interest
6. 24 months with 3 % interest
7. 30 months with 6 % interest
8. 36 months with 6 % interest

When going to financing, the longest rate will pull the product over to the more expensive general group. So when creating product specific groups always make sure to have the same months in all groups. They don't need to be complete, but they have to offer the same months.
When creating a group with a dynamic product group (product streams) always make sure that the group will contain at least one product. If the update through a cronjob clears out all products from the assignment, that group is considered a general group again. If the product is inactive, it still counts as product specific and thus is not used when looking for general groups.

It is recommended not to put in every single month value into the group as these have to manually be adjusted every time the values are changed on the CreditPlus side. The options offered inside the payment part are independent values.

-- 4. Working with product streams --

When using product streams or dynamic product groups, the products assigned there will be updated against the list currently assigned to the financing group. The cronjob will always first remove no longer assigned products and then add the new products to the list.
When you remove the dynamic product group from the financing product group, the last assigned set remains assigned until it is manually removed.

When you use these, the cron job "SicoGroupMapperTask" needs to run regularly to modify the assignments. This is needed, so that manual (or erp-based) assignments also work.
Also, if you want to keep the current state, you can just remove the dynamic product group from the financing group and then it remains locked and is skipped by the cron job.

-- 5. Recalculation of the cheapest rate --

The cheapest rates for product exports are calculated by the cron job "RateCalculatorTask". This task will run every minute and will calculate the cheapest rate for 100 products per sales channel in the shop.
The rates are calculated based on the current product price and the financing groups assigned to the product. The rates also depend on the sales channel used, as different sales channels might have different financing groups assigned to them.
If your rates have changed, you need to run the otherwise yearly cron job "RateCalculatorResetTask" to reset the "rate calculated" flag.
Then the first cron job will recalculate the rates for all products again.
