@@ -396,4 +396,194 @@ def test_floating_point_with_discounts
396396 # total: 3.14 + 0.69 = 3.83
397397 assert_equal BigDecimal ( "3.83" ) , line_item . total
398398 end
399+
400+ def test_add_surcharge_with_options
401+ line_item = Croatia ::Invoice ::LineItem . new ( description : "Test" )
402+
403+ surcharge = line_item . add_surcharge ( name : "Environmental fee" , amount : 2.50 )
404+
405+ assert_instance_of Croatia ::Invoice ::Surcharge , surcharge
406+ assert_equal "Environmental fee" , surcharge . name
407+ assert_equal BigDecimal ( "2.50" ) , surcharge . amount
408+ assert_equal 1 , line_item . surcharges . length
409+ end
410+
411+ def test_add_surcharge_with_block
412+ line_item = Croatia ::Invoice ::LineItem . new ( description : "Test" )
413+
414+ surcharge = line_item . add_surcharge ( name : "Recycling fee" , amount : 1.25 ) do |s |
415+ s . amount = 2.50 # Override the amount
416+ end
417+
418+ assert_instance_of Croatia ::Invoice ::Surcharge , surcharge
419+ assert_equal "Recycling fee" , surcharge . name
420+ assert_equal BigDecimal ( "2.50" ) , surcharge . amount
421+ assert_equal 1 , line_item . surcharges . length
422+ end
423+
424+ def test_add_surcharge_with_object
425+ line_item = Croatia ::Invoice ::LineItem . new ( description : "Test" )
426+ surcharge_obj = Croatia ::Invoice ::Surcharge . new ( name : "Handling fee" , amount : 3.75 )
427+
428+ result = line_item . add_surcharge ( surcharge_obj )
429+
430+ assert_equal surcharge_obj , result
431+ assert_equal 1 , line_item . surcharges . length
432+ assert_equal surcharge_obj , line_item . surcharges . values . first
433+ end
434+
435+ def test_remove_surcharge
436+ line_item = Croatia ::Invoice ::LineItem . new ( description : "Test" )
437+ line_item . add_surcharge ( name : "Delivery fee" , amount : 5.0 )
438+ line_item . add_surcharge ( name : "Service fee" , amount : 2.0 )
439+
440+ assert_equal 2 , line_item . surcharges . length
441+
442+ line_item . remove_surcharge ( "Delivery fee" )
443+
444+ assert_equal 1 , line_item . surcharges . length
445+ assert_nil line_item . surcharges [ "Delivery fee" ]
446+ refute_nil line_item . surcharges [ "Service fee" ]
447+ end
448+
449+ def test_clear_surcharges
450+ line_item = Croatia ::Invoice ::LineItem . new ( description : "Test" )
451+ line_item . add_surcharge ( name : "Fee 1" , amount : 1.0 )
452+ line_item . add_surcharge ( name : "Fee 2" , amount : 2.0 )
453+
454+ assert_equal 2 , line_item . surcharges . length
455+
456+ line_item . clear_surcharges
457+
458+ assert_equal 0 , line_item . surcharges . length
459+ end
460+
461+ def test_surcharge_calculation_single_surcharge
462+ line_item = Croatia ::Invoice ::LineItem . new (
463+ description : "Test item" ,
464+ quantity : 2 ,
465+ unit_price : 10.0
466+ )
467+ line_item . add_surcharge ( name : "Environmental fee" , amount : 2.50 )
468+
469+ assert_equal BigDecimal ( "2.50" ) , line_item . surcharge
470+ end
471+
472+ def test_surcharge_calculation_multiple_surcharges
473+ line_item = Croatia ::Invoice ::LineItem . new (
474+ description : "Test item" ,
475+ quantity : 2 ,
476+ unit_price : 10.0
477+ )
478+ line_item . add_surcharge ( name : "Environmental fee" , amount : 2.50 )
479+ line_item . add_surcharge ( name : "Handling fee" , amount : 1.75 )
480+
481+ assert_equal BigDecimal ( "4.25" ) , line_item . surcharge
482+ end
483+
484+ def test_surcharge_calculation_no_surcharges
485+ line_item = Croatia ::Invoice ::LineItem . new (
486+ description : "Test item" ,
487+ quantity : 2 ,
488+ unit_price : 10.0
489+ )
490+
491+ assert_equal BigDecimal ( "0.00" ) , line_item . surcharge
492+ end
493+
494+ def test_total_calculation_with_surcharges
495+ line_item = Croatia ::Invoice ::LineItem . new (
496+ description : "Test item" ,
497+ quantity : 2 ,
498+ unit_price : 10.0
499+ )
500+ line_item . add_tax ( rate : 0.25 )
501+ line_item . add_surcharge ( name : "Environmental fee" , amount : 3.0 )
502+
503+ # subtotal: 20.0, tax: 5.0, surcharge: 3.0, total: 28.0
504+ assert_equal BigDecimal ( "20.00" ) , line_item . subtotal
505+ assert_equal BigDecimal ( "5.00" ) , line_item . tax
506+ assert_equal BigDecimal ( "3.00" ) , line_item . surcharge
507+ assert_equal BigDecimal ( "28.00" ) , line_item . total
508+ end
509+
510+ def test_total_calculation_with_taxes_and_multiple_surcharges
511+ line_item = Croatia ::Invoice ::LineItem . new (
512+ description : "Test item" ,
513+ quantity : 1 ,
514+ unit_price : 100.0
515+ )
516+ line_item . add_tax ( rate : 0.25 )
517+ line_item . add_surcharge ( name : "Environmental fee" , amount : 5.0 )
518+ line_item . add_surcharge ( name : "Handling fee" , amount : 2.50 )
519+
520+ # subtotal: 100.0, tax: 25.0, surcharge: 7.5, total: 132.5
521+ assert_equal BigDecimal ( "100.00" ) , line_item . subtotal
522+ assert_equal BigDecimal ( "25.00" ) , line_item . tax
523+ assert_equal BigDecimal ( "7.50" ) , line_item . surcharge
524+ assert_equal BigDecimal ( "132.50" ) , line_item . total
525+ end
526+
527+ def test_surcharge_with_discount_and_tax
528+ line_item = Croatia ::Invoice ::LineItem . new (
529+ description : "Test item" ,
530+ quantity : 2 ,
531+ unit_price : 10.0
532+ )
533+ line_item . discount_rate = 0.1
534+ line_item . add_tax ( rate : 0.25 )
535+ line_item . add_surcharge ( name : "Service fee" , amount : 1.5 )
536+
537+ # gross: 20.0, discount: 2.0, subtotal: 18.0
538+ # tax: 18.0 * 0.25 = 4.5, surcharge: 1.5
539+ # total: 18.0 + 4.5 + 1.5 = 24.0
540+ assert_equal BigDecimal ( "20.00" ) , line_item . gross
541+ assert_equal BigDecimal ( "2.00" ) , line_item . discount
542+ assert_equal BigDecimal ( "18.00" ) , line_item . subtotal
543+ assert_equal BigDecimal ( "4.50" ) , line_item . tax
544+ assert_equal BigDecimal ( "1.50" ) , line_item . surcharge
545+ assert_equal BigDecimal ( "24.00" ) , line_item . total
546+ end
547+
548+ def test_surcharge_with_reverse_line_item
549+ line_item = Croatia ::Invoice ::LineItem . new (
550+ description : "Test item" ,
551+ quantity : 2 ,
552+ unit_price : 10.0
553+ )
554+ line_item . add_tax ( rate : 0.25 )
555+ line_item . add_surcharge ( name : "Fee" , amount : 3.0 )
556+ line_item . reverse
557+
558+ # After reverse, quantity is negative but surcharge remains positive
559+ assert_equal BigDecimal ( "-2" ) , line_item . quantity
560+ assert_equal BigDecimal ( "-20.00" ) , line_item . subtotal
561+ assert_equal BigDecimal ( "-5.00" ) , line_item . tax
562+ assert_equal BigDecimal ( "3.00" ) , line_item . surcharge # Surcharge stays positive
563+ assert_equal BigDecimal ( "-22.00" ) , line_item . total # -20 + (-5) + 3 = -22
564+ end
565+
566+ def test_surcharge_bigdecimal_precision
567+ line_item = Croatia ::Invoice ::LineItem . new ( description : "Test" )
568+ line_item . add_surcharge ( name : "Precision test" , amount : 1.234567 )
569+
570+ surcharge = line_item . surcharges [ "Precision test" ]
571+ assert_instance_of BigDecimal , surcharge . amount
572+ assert_equal BigDecimal ( "1.234567" ) , surcharge . amount
573+
574+ # Test that surcharge total is rounded to 2 decimal places
575+ assert_equal BigDecimal ( "1.23" ) , line_item . surcharge
576+ assert_equal 2 , line_item . surcharge . scale
577+ end
578+
579+ def test_initialize_with_surcharges
580+ surcharge = Croatia ::Invoice ::Surcharge . new ( name : "Initial fee" , amount : 2.0 )
581+ line_item = Croatia ::Invoice ::LineItem . new (
582+ description : "Test item" ,
583+ surcharges : { surcharge . name => surcharge }
584+ )
585+
586+ assert_equal 1 , line_item . surcharges . length
587+ assert_equal surcharge , line_item . surcharges [ "Initial fee" ]
588+ end
399589end
0 commit comments