Naar hoofdinhoud

Handleiding

Deze handleiding beschrijft een aantal specifieke zaken binnen de EVtoolbox.

 

Voorbeeld auto

Hieronder een data van de Kia e-Niro - ev plus 3-fase 150kW aut.

car Kia e-Niro
versie ev plus 3-fase 150kW aut
car_ad_type_id_hist
car_mileage 46 KMT
car_model_year 2024
car_first_registration
car_production_date --
car_fuel_type
car_age_in_months --
car_co2_emissions
car_max_contract_duration maand(en)
car_bijtelling %
car_price_buy_for_offered_country € 0 incl. btw. / incl. bpm

 

Financieringsvormen

Binnen de EVtoolbox werken we met de volgende financieringsvormen. Op dit moment zijn enkel fol en flz uitgewerkt en opvraagbaar Deze worden hieronder verder toegelicht. De flp wordt ook reeds berekend, maar wordt nog nergens ontsloten.

title site value
Netto Operational Lease nol
Full Operational Lease Lease-e website fol
Financial Lease Zakelijk Lease-e financial lease website flz
Financial Lease Particulier flp
Private Lease prl
Koop Mobido website kp

 

Rekenvoorbeeld

Hieronder het rekenvoorbeeld.

omschrijving bedrag sub opmerking
inkoop
1 geadverteerde NL prijs € 36490,00 incl. NL BTW / incl. BPM
2 BPM uit de prijs € 36490,00 € 0,00 BPM (AT) moet er uit als NL en BTW auto
3 NL BTW uit de prijs € 30157,02 € 6332,98 dit is dus de excl. BTW prijs (BTW auto)
4 aankoopbedrag € 30157,02 excl. BTW excl. BPM
5 additionele posten € 0,00 totaal, zie specificatie hieronder
5a transportkosten € 0,00 deze hoger als land!= NL
5b keuringskosten € 0,00 alleen vanuit het buitenland
5c schade herstel € 0,00
5d onderhoudsbeurt € 0,00
5e garantie € 0,00 0% over de aankoopprijs van € 30157,02 uit stap 4
6 inkoopbedrag € 30157,02 aankoopbedrag van € 30157,02 uit stap 4 + additionele posten van € 0,00 uit stap 5
verkoop
7 winstmarge € 0,00 0% marge van het aankoopbedrag € 30157,02 uit stap 4
8 btw toeslag marge auto € 0,00
9 korting vanuit verkoop (SF) € 0,00 € 0,00 subtotaal kortingen (€ 0,00 incl. BTW)
10 verkoopbedrag auto
excl. BTW excl. BPM
€ 30157,02 inkoopbedrag van € 30157,02 + winstmarge resultaat van € 0,00 + evt. btw toeslag van € 0,00 - korting van € 0,00 uit stap 9
11 BPM € 0,00 voor een 'Elektrisch' voertuig met 0 gram CO2 emissies
12 excl. BTW incl. BPM € 30157,02
12a BTW over de auto € 6332,98 21% over verkoopprijs van € 30157,02 uit stap 10
13 incl. BTW incl. BPM € 36490,00
extra's vanuit verkoop
14 extra's vanuit verkoop (SF) € 0,00 € 0,00 subtotaal additionele verkoop (€ 0,00 incl. BTW)
verkoopprijs auto incl. extra's
15 excl. BTW incl. BPM € 30157,02 FLz
15a BTW totaal € 6332,98 BTW over de auto van € 6332,98 uit stap 10a + BTW over de extra's van € 0,00 uit stap 12
16 incl. BTW incl. BPM € 36490,00 FOL, NOL, PRL en KP en FLp

 

 

Calculation help

Onderstaande overzicht alle communicatie tussen SalesForce en de EVtoolbox.

enforce_update_calculation | API call SF -> EVT

Deze call wordt aangeroepen vanuit SalesForce. Er worden uit de calculatie variabelen ingelezen, de calculatie wordt uitgevoerd en het resultaat wordt weer ingeschoten bij SalesForce.

https://www.evtoolbox.nl/api/salesforce/enforce_update_calculation/a010600002UIQ3QAAX

def enforce_update_calculation(request, sf_calculation_id): calculation.run(params={ 'additional_calculations': get_from_sf_object(sf_calculation, 'sf_total_calculation_line_price__c'), 'discount_price': get_from_sf_object(sf_calculation, 'sf_discount_price__c'), 'profit_margin': get_from_sf_object(sf_calculation, 'sf_profit_margin__c'), 'insurance_percentage': get_from_sf_object(sf_calculation, 'sf_insurance_percentage__c'), 'transportation_costs': get_from_sf_object(sf_calculation, 'sf_transportation_costs__c'), 'inspection_costs': get_from_sf_object(sf_calculation, 'sf_inspection_costs__c'), 'damage_repair': get_from_sf_object(sf_calculation, 'sf_damage_repair__c'), 'maintenance': get_from_sf_object(sf_calculation, 'sf_maintenance__c'), }) # Koop if contract_type.slug in ['kp']: matrix = calculation.get_kp_matrix() # Full Operational Lease # Netto Operational Lease # Private Lease if contract_type.slug in ['nol','fol','prl']: includesTiresOption = get_from_sf_object(sf_calculation, 'evt_includes_tires_option__c') input_params = { 'down_payment': get_from_sf_object(sf_calculation, 'evt_down_payment__c'), 'annualKilometers': get_from_sf_object(sf_calculation, 'evt_requested_kilometers__c'), 'duration': get_from_sf_object(sf_calculation, 'evt_duration_in_months__c'), 'includeDepreciation': get_from_sf_object(sf_calculation, 'evt_includes_depreciation__c'), 'includesInsurance': get_from_sf_object(sf_calculation, 'evt_includes_insurance__c'), 'includesReplacementVehicle': get_from_sf_object(sf_calculation, 'evt_includes_replacement_vehicle__c'), 'includesFuel': get_from_sf_object(sf_calculation, 'evt_includes_fuel__c'), 'includesFuelPass': get_from_sf_object(sf_calculation, 'evt_includes_fuel_pass__c'), 'includeHoldingTax': get_from_sf_object(sf_calculation, 'evt_includes_holding_tax__c'), 'includeRepairMaintenance': get_from_sf_object(sf_calculation, 'evt_includes_repair_maintenance__c'), 'includeServiceCard': get_from_sf_object(sf_calculation, 'evt_includes_service_card__c'), } matrix = calculation.get_nol_fol_prl_matrix( contract_type_slug=contract_type.slug, input_params=input_params, ) # Financial Lease Zakelijk # Financial Lease Particulier if contract_type.slug in ['flz','flp']: input_params = { 'invest_amount': invest_amount, 'contract_time': get_from_sf_object(sf_calculation, 'evt_duration_in_months__c'), 'result': get_from_sf_object(sf_calculation, 'evt_bullet_amount__c'), 'down_payment': get_from_sf_object(sf_calculation, 'evt_down_payment__c'), 'interest': get_from_sf_object(sf_calculation, 'evt_interest_percentage__c'), } matrix = calculation.get_fl_matrix(contract_type_slug=contract_type.slug, input_params=input_params)

patch_sf_calculation | API call EVT -> SF

Deze call wordt ingeschoten bij SalesForce, bijvoorbeeld naar aanleiding van de enforce_update_calculation.

def patch_sf_calculation(logger, sf_session, sf_calculation_id, contract_type, calculation, car, matrix, warnings): kp_data = calculation.get_kp_data() sf_calculation_data = { "evt_fiscale_waarde__c": kp_data['fiscale_waarde'], "evt_investment_amount_tax__c": kp_data['vat'], "evt_investment_amount_bpm__c": kp_data['bpm'], "evt_investment_amount__c": kp_data['price_incl_bpm_excl_vat'], "evt_purchase_price__c": kp_data['price_incl_bpm_incl_vat'], "sf_insurance_percentage__c": kp_data['insurance_percentage'], "sf_profit_margin__c": kp_data['profit_margin'], "sf_transportation_costs__c": kp_data['transportation_costs'], "sf_inspection_costs__c": kp_data['inspection_costs'], "sf_damage_repair__c": kp_data['damage_repair'], "sf_maintenance__c": kp_data['maintenance'], } # Koop if contract_type.slug in ['kp']: # nothing need to be done here, since everything is updated above # Full Operational Lease # Netto Operational Lease # Private Lease if contract_type.slug in ['nol','fol','prl']: sf_calculation_data["evt_duration_in_months__c"] = matrix['contract_duration'] sf_calculation_data["evt_requested_kilometers__c"] = matrix['mileage'] sf_calculation_data["evt_price_per_month__c"] = matrix['price_excl_fuel'] sf_calculation_data["evt_down_payment__c"] = matrix['down_payment'] sf_calculation_data["evt_investment_amount__c"] = matrix['invest_amount'] sf_calculation_data["evt_rest_value__c"] = matrix['rest_value']['price'] # component prices sf_calculation_data[f"evt_comp_Admin__c"] = get_component_price_from_matrix(matrix, 'comp_Admin') sf_calculation_data[f"evt_comp_AfschrijvingBPM__c"] = get_component_price_from_matrix(matrix, 'comp_AfschrijvingBPM') sf_calculation_data[f"evt_comp_Brandstof__c"] = get_component_price_from_matrix(matrix, 'comp_Brandstof') sf_calculation_data[f"evt_comp_BPas__c"] = get_component_price_from_matrix(matrix, 'comp_BPas') sf_calculation_data[f"evt_comp_HSB__c"] = get_component_price_from_matrix(matrix, 'comp_HSB') sf_calculation_data[f"evt_comp_Afschrijving__c"] = get_component_price_from_matrix(matrix, 'comp_Afschrijving') sf_calculation_data[f"evt_comp_ManFee__c"] = get_component_price_from_matrix(matrix, 'comp_ManFee') sf_calculation_data[f"evt_comp_Rente__c"] = get_component_price_from_matrix(matrix, 'comp_Rente') sf_calculation_data[f"evt_comp_RO__c"] = get_component_price_from_matrix(matrix, 'comp_RO') sf_calculation_data[f"evt_comp_Service__c"] = get_component_price_from_matrix(matrix, 'comp_Service') sf_calculation_data[f"evt_comp_VV__c"] = get_component_price_from_matrix(matrix, 'comp_VV') sf_calculation_data[f"evt_comp_Verzekering__c"] = get_component_price_from_matrix(matrix, 'comp_Verzekering') sf_calculation_data[f"evt_comp_B__c"] = get_component_price_from_matrix(matrix, 'comp_B') sf_calculation_data[f"evt_comp_WB__c"] = get_component_price_from_matrix(matrix, 'comp_WB') # Financial Lease Zakelijk # Financial Lease Particulier if contract_type.slug in ['flz','flp']: sf_calculation_data["evt_investment_amount__c"] = matrix['invest_amount'] sf_calculation_data["evt_bullet_amount__c"] = matrix['result'] sf_calculation_data["evt_down_payment__c"] = matrix['down_payment'] sf_calculation_data["evt_duration_in_months__c"] = matrix['contract_time'] sf_calculation_data["evt_interest_percentage__c"] = matrix['interest'] sf_calculation_data["evt_price_per_month__c"] = matrix['price']

Calculation model

Dit is de plek waar de calculatie plaats vindt.

https://www.evtoolbox.nl/db/testsuite/calculation/

# INKOOP car_fiscale_waarde = car.version.get_ad_fiscale_waarde() if car and car.version else None # step 1 car_license_plate = params_run.get('license_plate', car.license_plate if car else None) car_production_date = get_date(params_run.get('car_production_date', None), car.get_car_production_date() if car else None) car_mileage = params_run.get('car_mileage', car.get_display_mileage() if car else None) car_fuel_type = params_run.get('car_fuel_type', car.get_display_fuel_type() if car else None) car_co2_emissions = params_run.get('car_co2_emissions', car.get_co2_uitstoot() if car else None) car_offered_by_country = params_run.get('car_offered_by_country', car.offered_by_country if car and car.offered_by_country else None) car_is_btw_car = params_run.get('car_is_btw_car', car.btw_car if car else False) car_bpm = get_car_bpm( car_first_registration_date=car_production_date, # use production_date as first_registration car_fuel_type=car_fuel_type, car_co2_emissions=car_co2_emissions, car_mileage=car_mileage, car_is_btw_car=car_is_btw_car, car_license_plate=car_license_plate, ) car_price_buy_for_offered_country = params_run.get('car_price_buy_for_offered_country', car.price_buy if car and car.price_buy else 0) # step 2 # only remove BPM from price if car is btw car and from the Netherlands bpm_should_be_processed = True if car_is_btw_car and car_offered_by_country == 'NL' else False car_price_excl_bpm = (car_price_buy_for_offered_country - car_bpm) if car_price_buy_for_offered_country and car_bpm and bpm_should_be_processed else car_price_buy_for_offered_country # step 3 # remove vat from price vat_for_country = get_vat_for_country(car_offered_by_country) vat_for_nl = get_vat_for_country('NL') car_price_excl_bpm_excl_vat = ((car_price_excl_bpm / (100 + vat_for_country)) * 100) if car_is_btw_car else car_price_excl_bpm car_price_vat = (car_price_excl_bpm - car_price_excl_bpm_excl_vat) if car_is_btw_car else 0 # step 4 - subtotal car_purchase_amount = car_price_excl_bpm_excl_vat # aankoopbedrag # step 5 insurance_percentage = get_float_or_int_from_dict( dict_name=params_run, dict_key='insurance_percentage', float_or_int='float', value_default=get_scs_default_value(scs=scs_kp, key='insurance_percentage'), ) if not skip_steps_5a_and_7a else 0 transportation_costs = get_float_or_int_from_dict( dict_name=params_run, dict_key='transportation_costs', float_or_int='int', value_default=get_scs_default_value(scs=scs_kp, key='transportation_costs'), ) if not skip_steps_5a_and_7a else 0 inspection_costs = get_float_or_int_from_dict( dict_name=params_run, dict_key='inspection_costs', float_or_int='int', value_default=get_scs_default_value(scs=scs_kp, key='inspection_costs'), ) if not skip_steps_5a_and_7a else 0 damage_repair = get_float_or_int_from_dict( dict_name=params_run, dict_key='damage_repair', float_or_int='int', value_default=get_scs_default_value(scs=scs_kp, key='damage_repair'), ) if not skip_steps_5a_and_7a else 0 maintenance = get_float_or_int_from_dict( dict_name=params_run, dict_key='maintenance', float_or_int='int', value_default=get_scs_default_value(scs=scs_kp, key='maintenance'), ) if not skip_steps_5a_and_7a else 0 inspection_costs_should_be_added = params_run.get('inspection_costs_should_be_added', False if car_offered_by_country == 'NL' else True) if not skip_steps_5a_and_7a else False insurance = get_percentage(amount=car_purchase_amount, percentage=insurance_percentage) car_posts_price = ( (transportation_costs) + (inspection_costs if inspection_costs_should_be_added else 0) + (damage_repair) + (maintenance) + (insurance) ) # step 6 - inkoopbedrag car_purchase_price = float(car_purchase_amount) + float(car_posts_price) # VERKOOP # step 7 profit_margin = get_float_or_int_from_dict( dict_name=params_run, dict_key='profit_margin', float_or_int='float', value_default=get_scs_default_value(scs=scs_kp, key='profit_margin'), ) if not skip_steps_5a_and_7a else 0 car_profit_margin = get_percentage( amount=car_purchase_amount, percentage=profit_margin, ) # step 8 # 21% vat for marge cars car_profit_vat_addition = get_percentage( amount=car_profit_margin, percentage=vat_for_nl, ) if not car_is_btw_car else 0 # step 9 sf_discount_price = params_run.get('discount_price', 0) discount_price_without_vat = (sf_discount_price / (1 + (vat_for_nl / 100))) if car_is_btw_car else (sf_discount_price) if sf_discount_price else 0 discount_price_vat = (sf_discount_price - discount_price_without_vat) if car_is_btw_car and sf_discount_price else 0 # step 10 car_sell_price = ( car_purchase_price + car_profit_margin + car_profit_vat_addition - discount_price_without_vat ) # step 11 bpm_should_be_added = True if car_is_btw_car else False car_total_calculation_price_incl_bpm_excl_vat_excl_extra = round((float(car_sell_price) + (float(car_bpm) if bpm_should_be_added else 0)), 2) # step 12a # voor BTW auto over total_price # voor marge auto over additonele posten en accessoires # niet over de additionele posten, maar wel over de accessoires car_totalprice_vat = get_percentage( amount=car_sell_price, percentage=vat_for_nl, ) if car_is_btw_car else 0 # step 13 car_total_buy_price_incl_bpm_incl_vat_excl_extra = round(( float(car_sell_price) + # car_sell_price (float(car_totalprice_vat) if car_is_btw_car else 0) + (float(car_bpm) if bpm_should_be_added else 0) ), 2) # step 14 sf_additional_calculations = params_run.get('additional_calculations', 0) additional_calculations_without_vat = (sf_additional_calculations / (1 + (vat_for_nl / 100))) if sf_additional_calculations else 0 additional_calculations_vat = (sf_additional_calculations - additional_calculations_without_vat) if sf_additional_calculations else 0 # step 15 car_total_calculation_price_incl_bpm_excl_vat = round(( (float(car_sell_price) + float(additional_calculations_without_vat)) + (float(car_bpm) if bpm_should_be_added else 0) ), 2) # step 15a total_vat = car_totalprice_vat + additional_calculations_vat # step 16 car_total_buy_price_incl_bpm_incl_vat = round(( (float(car_sell_price) + float(additional_calculations_without_vat)) + (float(total_vat) if car_is_btw_car else float(additional_calculations_vat)) + (float(car_bpm) if bpm_should_be_added else 0) ), 2) # step QUOTE quote_vehicle_price = ( car_total_buy_price_incl_bpm_incl_vat_excl_extra + sf_discount_price ) # = incl. btw, incl. bpm, excl korting excl extra's quote_additional_calculations = sf_additional_calculations # other quote_subtotal = ( quote_vehicle_price + sf_additional_calculations ) # subtotal quote_discount_incl_vat = sf_discount_price # korting quote_total_price = quote_subtotal - quote_discount_incl_vat quote_total_price_check = car_total_buy_price_incl_bpm_incl_vat # total

Matrices

Dit zijn de resultaten van een calculatie voor de verschillende contract-types.

#KOOP matrix = { 'bpm': car_bpm, 'vat': round(total_vat, 2), 'insurance_percentage': insurance_percentage, 'profit_margin': profit_margin, 'transportation_costs': transportation_costs, 'inspection_costs': inspection_costs, 'damage_repair': damage_repair, 'maintenance': maintenance, 'car_fuel_type': car_fuel_type, 'car_is_btw_car': car_is_btw_car, 'car_co2_emissions': car_co2_emissions, 'car_production_date': f"{car_production_date}", 'car_offered_by_country': car_offered_by_country, 'car_price_buy_for_offered_country': car_price_buy_for_offered_country, 'price_incl_bpm_excl_vat': car_total_calculation_price_incl_bpm_excl_vat, 'price_incl_bpm_incl_vat': car_total_buy_price_incl_bpm_incl_vat, } #NETTO OPERATIONAL LEASE #FULL OPERATIONAL LEASE #PRIVATE LEASE matrix = { 'down_payment': down_payment, 'invest_amount': invest_amount, 'mileage': annualKilometers, 'contract_duration': duration, 'mantel': frameworkAgreementNumber, 'price_incl_fuel': leasePrijsInBrandstof, 'price_excl_fuel': leasePrijsExBrandstof, 'price': leasePrijsInBrandstof if 'includesFuel' in params and includesFuel else leasePrijsExBrandstof, 'rest_value': rest_value, } #FINANCIAL LEASE ZAKELIJK #FINANCIAL LEASE PARTICULIER matrix = { 'price': price, 'interest': interest, 'invest_amount': invest_amount, 'down_payment': down_payment, 'result': result, 'contract_time': contract_time, }

 

Financial Lease zakelijk

Onderstaand gedeelte gaat over het berekenen van de Financial lease voor de zakelijke doelgroep, de flz. Deze berekening wordt zelf uitgevoerd binnen de EVtoolbox en is eerder gebruikt binnen de Aiways website. Hiervoor zijn een aantal instelbare en beheerbare variabelen beschikbaar, te weten:

contract title key value type description
Financial Lease Zakelijk Contractduur contract_duration 72 getal
Financial Lease Zakelijk Aanbetaling klant (default) downpayment 10% percentage
Financial Lease Zakelijk Slotsom klant final_term 10% percentage
Financial Lease Zakelijk Slotsom bij 24 maanden final_term_24_months 35% percentage
Financial Lease Zakelijk Slotsom bij 36 maanden final_term_36_months 35% percentage
Financial Lease Zakelijk Slotsom bij 48 maanden final_term_48_months 30% percentage
Financial Lease Zakelijk Slotsom bij 60 maanden final_term_60_months 25% percentage
Financial Lease Zakelijk Slotsom bij 72 maanden final_term_72_months 15% percentage
Financial Lease Zakelijk DHG rentepercentage interest 7.99% percentage
Financial Lease Zakelijk DHG marge margin 5% percentage
Financial Lease Zakelijk Aanbetaling klant (max) max_downpayment 80% percentage
Financial Lease Zakelijk Aanbetaling klant (min) min_downpayment 0 getal

 

Voor de berekeningen is een speciale testsuite ingericht en uitleg over deze berekeningen zijn daar te vinden. Onderstaand stuk code laat zien hoe de instelbare variabelen gebruikt worden om tot bepaalde getallen te komen. De waardes tussen [blokhaken] komen uit bovenstaande tabel.

 

Wanneer deze waardes berekend zijn kunnen deze ingevoerd worden in de formule welke tot de leesprijs komt. In het voorbeeld wordt middels het debug knopje de opbouw van de prijs getoond.

motiv > helpers > calculations.py

def calculate_fl_price(invest_amount, interest, down_payment, result, contract_time):

  price = round(npf.pmt(
    interest / 12,
    contract_time,
    -(invest_amount - down_payment),
    fv=result
  ),2)
        

 

Full Operational Lease

Voor de berekening van de Full Operational Lease wordt gebruik gemaakt van AutoDisk. Voor de berekening van deze prijzen zijn een looptijd (contractduur) en het verwacht aantal kilometers per jaar relevant. Ook is het belangrijk dat de auto goed ge-versie-matcht is, aangezien AutoDisk oa. het ntypeidhist, nkentekendatumdeeleen en nkmstand gebruikt in de berekeningen. Wanneer een auto niet goed is gematcht kan het zijn dat er een verkeerde prijs en/of geen prijs teruggegeven wordt door AutoDisk. Deze prijs dient dus altijd op 'sanity' gecheckt te worden.

Het voorbeeld hierboven toont tevens de debug informatie voor de Full Operational Lease prijs. In de berekening worden een aantal controles gedaan. Zo is de maximale contractduur (standaard 72 maanden) afhankelijk van de leeftijd van de auto. Soms wordt deze dus automatisch naar beneden bijgesteld.

 

Voorbeeld

Hieronder een rekenvoorbeeld voor de Kia e-Niro. Refresh (F5) deze pagina voor een ander voorbeeld.

Full Operational Lease = Autodisk calculatie
price_fol_updated_date 4 juli 2025 01:58
price_fol (debug) 629,81 p/m
price_fol_contract_duration 60 mnd
price_fol_contract_mileage 10000 km

 

Private Lease = Autodisk calculatie
price_prl_updated_date 4 juli 2025 01:58
price_prl (debug) 634,81 p/m
price_prl_contract_duration 60 mnd
price_prl_contract_mileage 10000 km

 

Financial Lease = 'Aiways' calculatie
price_fl_updated_date 3 juni 2025 09:57
price_flz (debug) 426,59 p/m
price_flz_contract_duration 72 mnd
price_flp (debug) 516,16 p/m
price_flp_contract_duration 72 mnd

 

Koop = eigen prijsopbouw, zie testsuite
price_fol_updated_date 3 juni 2025 09:57
price_kp incl. btw incl. bpm (debug) 36.490,00

 

Restwaarde = afkomstig van FOL, NOL of PRL calculatie bij AD
price_incl_bpm_excl_vat € 30.157,02
contract_duration 60 mnd
write_off € 302,64
write_off_bpm € 3,73
price 11.774,82