package distribution

// Zero-shipment guard on DeliverDeliveryOrder.
//
// The method used to complete any non-cancelled DO unconditionally: with no
// shipments at all it skipped the shipment loop and still wrote delivered =
// requested, recording a delivery that never happened and flipping the sales
// order to delivered with it. Completing now requires something to have
// actually shipped.

import (
	"context"
	"errors"
	"testing"

	"github.com/shopspring/decimal"
)

func TestDeliverDeliveryOrder_RefusesZeroShipments(t *testing.T) {
	f := newFakeStore()
	f.mustSO(t, 1, 2, "confirmed", 10)
	f.addStock(10, 2, decimal.NewFromInt(500), decimal.NewFromInt(500))
	svc := newService(f)
	o := f.mustDO(t, svc, 1, 10)

	if _, err := svc.DeliverDeliveryOrder(context.Background(), o.ID, 1, nil, ""); !errors.Is(err, ErrNothingShipped) {
		t.Fatalf("got %v, want ErrNothingShipped", err)
	}
	// The refusal must leave everything untouched.
	got, err := svc.GetDeliveryOrder(context.Background(), o.ID)
	if err != nil {
		t.Fatal(err)
	}
	if got.Status == StatusCompleted {
		t.Fatal("DO with nothing shipped must not complete")
	}
	if f.sos[1].Status != "confirmed" {
		t.Fatalf("SO status = %q, want confirmed (nothing delivered)", f.sos[1].Status)
	}
}

func TestDeliverDeliveryOrder_RefusesAllShipmentsCancelled(t *testing.T) {
	f := newFakeStore()
	f.mustSO(t, 1, 2, "confirmed", 10)
	f.addStock(10, 2, decimal.NewFromInt(500), decimal.NewFromInt(500))
	svc := newService(f)
	o := f.mustDO(t, svc, 1, 10)

	sh, err := svc.CreateShipment(context.Background(), o.ID, ShipmentInput{
		Items: []ShipmentItemInput{{ProductID: 10, ShippedQuantity: decimal.NewFromInt(100)}},
	}, 1)
	if err != nil {
		t.Fatal(err)
	}
	f.shipments[sh.ID].Status = ShipmentCancelled

	if _, err := svc.DeliverDeliveryOrder(context.Background(), o.ID, 1, nil, ""); !errors.Is(err, ErrNothingShipped) {
		t.Fatalf("got %v, want ErrNothingShipped", err)
	}
	got, err := svc.GetDeliveryOrder(context.Background(), o.ID)
	if err != nil {
		t.Fatal(err)
	}
	if got.Status == StatusCompleted {
		t.Fatal("DO with only cancelled shipments must not complete")
	}
}
