spec.md 6.9 KB

Spec Delta

Purpose

Allow the same product and package specification on multiple contract lines, bind transport-plan stop products to those lines for target and actual quantities, and keep contracts hidden from drivers and site staff.

ADDED Requirements

Requirement: Contract allows duplicate product and package spec lines

The system SHALL allow multiple product lines on the same contract to share the same productId and the same package specification, each with its own quantity and price. Each line MUST still have at least one package specification. A single line MAY still carry multiple package specifications that share that line's quantity pool. The system MUST NOT reject save solely because two lines reuse the same product and package specification.

Scenario: Same product and package with different prices

  • WHEN a user saves two contract product lines for the same product and package specification with prices 800 and 850 and quantities 50 and 40
  • THEN the system persists both lines and does not return a duplicate-package validation error

Scenario: Multi-package shared pool still valid

  • WHEN a user saves one line with package specs 25kg/桶 and 槽罐车 and quantity 715
  • THEN the system persists both specs on that line with quantity 715 as the shared pool for that line only

Requirement: Plan stop may bind multiple contracts of the same customer

When a load or delivery stop is not an internal customer, the system SHALL require at least one contract and SHALL allow more than one contract on that stop. Every selected contract MUST belong to that stop's customer. The system MUST NOT reject save solely because a stop has two contracts.

Scenario: Two contracts on one delivery stop

  • WHEN a planner selects contracts A and B for the same delivery customer and saves the plan
  • THEN the system persists both contract links on that stop

Scenario: External stop without contract is rejected

  • WHEN a planner saves a non-internal load or delivery stop with no contract
  • THEN the system rejects the save with a message requiring a contract for that stop

Requirement: Plan stop products bind to a contract product line

When a stop product is created against selected contracts, the system SHALL persist contractId and contractProductId on that stop product row, together with a target quantity (planQty). The product and package on the row MUST match the bound contract line. The same physical goods MAY appear as multiple stop product rows, each bound to a different contract line. Internal-customer or no-contract stops MAY omit contract line binding.

Scenario: Planner adds two rows for the same product and package

  • WHEN a planner adds one stop product bound to contract A line 1 with target 10 and another bound to contract B line 1 with target 20 for the same product and package
  • THEN the system persists two rows with distinct contractProductId values and target quantities 10 and 20

Scenario: Product picker lists contract lines not product names only

  • WHEN a planner opens add-product for a stop that has contracts with two lines sharing product and package but different prices
  • THEN the picker shows both lines distinguished by contract number, package, price, and remaining quantity

Requirement: Quantity occupancy keys by contract product line

Available quantity, arranged totals, archived totals, remaining, and arrange-time hard checks SHALL use the bound contractProductId (the line quantity pool, including all packages on that line). The system MUST NOT merge occupancy across different lines that share product and package. Unarchived arranged plans SHALL occupy using target quantity; archived plans SHALL occupy using actual quantity. Historical stop products without contractProductId MAY fall back to matching by product and package membership.

Scenario: Independent remaining on duplicate package lines

  • WHEN contract A has two lines of the same product and package with quantities 50 and 40, and counted plans have arranged 10 against line 1 only
  • THEN querying arrange-qty for line 1 returns remaining 40 and querying line 2 returns remaining 40

Scenario: Save plan may exceed remaining

  • WHEN a planner saves a draft or update whose target quantity on a bound line exceeds that line's remaining
  • THEN the system persists the plan without treating the excess as a blocking error

Scenario: Arrange transport hard-blocks excess target

  • WHEN a user arranges transport and any bound stop product target quantity exceeds that line's remaining (excluding this plan's existing occupancy as applicable)
  • THEN the system rejects arrange and names the overflowing contract line; it MUST NOT apply the excess to another same-product line

Requirement: Archive confirms actual quantity per bound line

On archive, the system SHALL record actual quantity on each already-split stop product row (load inbound / delivery outbound). When a vehicle or inbound/outbound total is present, the sum of actual quantities on the relevant stop products MUST equal that total. Actuals MAY default to each row's target quantity. If any row's actual quantity exceeds that line's remaining, the system SHALL highlight those rows, list contract number, product, package, price or line identity, remaining, actual, and excess, and MUST NOT archive until the user confirms. After confirmation, excess MUST post only to the named lines. Remaining MAY become negative and MUST be shown as over-delivery, not merged into another line.

Scenario: Actuals must match weighbridge total

  • WHEN a user archives with weighbridge total 30.2 and stop actuals summing to 30.0
  • THEN the system rejects archive until the actuals sum equals 30.2

Scenario: Over-remaining requires second confirmation

  • WHEN a user archives with aligned totals but one bound line actual 55 against remaining 50
  • THEN the system shows a confirmation listing that line and excess 5, and archives only after the user confirms; the line archived quantity becomes 55 and remaining shows over-delivery 5

Scenario: Draft archive may warn without forcing confirm

  • WHEN a user saves an archive draft with a row over remaining
  • THEN the system may persist the draft with visible warning and MUST NOT require the over-delivery confirmation until formal archive

Requirement: Drivers and site staff do not see contract allocation

Driver and site interfaces SHALL display product, package, and quantity for the vehicle or stop. They MUST NOT require selecting a contract or contract product line, and MUST NOT present contract number or unit price as operational fields for completing load or delivery.

Scenario: Driver task shows aggregated goods only

  • WHEN a driver opens a plan that internally has three contract-line rows of the same product totaling 30 tons
  • THEN the driver UI shows that product and approximately 30 tons without listing the three contracts