dodil/erp-brick-sales-order
DODIL ERP brick: sales order
tests/test_v8.py
"""Spec v8: the ship-to address object (and what a drop-ship line needs), SO-50 demand for planning, the tool names."""
from conftest import ADDRESS, ADMIN, INVENTORY, REP, SYSTEM, api, confirm, deliver, hand, must
from test_slice_b import JUICE, warehouse_set
def test_the_ship_to_address_is_the_object_the_order_keeps_shows_and_sends_to_purchasing(neighbours, inventory):
o = hand(REP, ship_to_bp_id=7313, ship_to_address=ADDRESS, lines=[{"product_id": "PRINTER-X", "quantity": "2", "unit_code": "C62", "usage": "drop_ship"}])
assert o["ship_to_address"] == {"lines": ["1 High Street"], "city": "London", "postcode": "N1 1AA", "region": None, "country": "GB"}
assert o["ship_to_country"] == "GB"
o = confirm(o)
sent = neighbours.purchasing.requests[f"so:{o['sales_order_id']}:1@r1"]
assert sent["ship_to_address"] == o["ship_to_address"]
again = must(api("GET", f"/sales-orders/{o['sales_order_id']}", REP))
assert again["ship_to_address"]["city"] == "London"
def test_a_drop_ship_line_cannot_be_confirmed_without_the_delivery_address(neighbours, inventory):
o = must(api("POST", "/sales-orders", REP, {"bp_id": 7311, "currency": "GBP", "ship_to_bp_id": 7313,
"lines": [{"product_id": "PRINTER-X", "quantity": "2", "unit_code": "C62", "usage": "drop_ship"}]}))
assert o["ship_to_address"] is None
s, b = api("POST", f"/sales-orders/{o['sales_order_id']}/confirm", REP, {})
assert s == 422 and b["gate"] == "ship_to_address"
assert api("POST", "/sales-orders", REP, {"bp_id": 7311, "currency": "GBP", "ship_to_address": {"lines": ["x"], "city": "L", "country": "gb"},
"lines": [{"product_id": "SETUP", "quantity": "1", "unit_code": "HUR"}]})[0] == 422
def test_so50_open_quantity_of_confirmed_goods_lines_from_a_warehouse_without_prices(neighbours, inventory):
warehouse_set("WH1")
keep = confirm(hand(REP, lines=JUICE))
must(api("POST", "/sales-orders", REP, {"bp_id": 7311, "currency": "GBP", "lines": JUICE})) # a draft is not demand
gone = confirm(hand(REP, lines=JUICE))
must(api("POST", f"/sales-orders/{gone['sales_order_id']}/cancel", ADMIN, {"reason": "no"})) # nor a cancelled order
out = must(api("GET", "/demand", SYSTEM, {"product_id": "JUICE-075", "warehouse_id": "WH1", "from": "2026-11-01", "to": "2027-12-31"}))
assert [(d["sales_order_id"], d["line_no"], d["open_quantity"], d["unit_code"], d["open_base"]) for d in out["demand"]] == \
[(keep["sales_order_id"], 1, "480", "C62", "360")]
assert out["more"] is False and not {"unit_price", "net_amount", "bp_id", "total"} & set(out["demand"][0])
must(deliver(keep, 1, 100, "inv:D-1", INVENTORY, source="inventory"))
again = must(api("GET", "/demand", SYSTEM, {"product_id": "JUICE-075", "warehouse_id": "WH1", "from": "2026-11-01", "to": "2027-12-31"}))
assert again["demand"][0]["open_quantity"] == "380"
other = must(api("GET", "/demand", SYSTEM, {"product_id": "JUICE-075", "warehouse_id": "WH9", "from": "2026-11-01", "to": "2027-12-31"}))
assert other["demand"] == []
assert api("GET", "/demand", REP, {"product_id": "JUICE-075", "warehouse_id": "WH1", "from": "2026-11-01", "to": "2027-12-31"})[0] == 403 # machine only
assert api("GET", "/demand", SYSTEM, {"product_id": "JUICE-075", "warehouse_id": "WH1", "from": "2026-12-01", "to": "2026-11-01"})[0] == 422
def test_the_shared_family_tools_name_the_module_noun():
from brick_sales_order.application import use_cases
names = {uc.name for uc in use_cases.SO.use_cases}
assert {"cancel_draft_order", "accept_order_suggestion", "reconcile_order_migration", "get_demand"} <= names
assert not {"cancel_draft", "accept_suggestion", "reconcile_odoo_orders"} & names