syntax = "proto3";
package procurement;
// import "prelude.proto";
import "google/protobuf/empty.proto";

service Procurement {
  // Create new Procurement
  rpc CreateNew(CreateNewRequest) returns (ProcurementObject);
  // Get by ID
  rpc GetById(GetByIdRequest) returns (ProcurementObject);
  // Get all procurement IDs
  rpc GetAll(google.protobuf.Empty) returns (ProcurementIds);
  // Get info in bulk
  rpc GetInfoBulk(GetInfoBulkRequest) returns (stream ProcurementInfoObject);
  // Try removes a procurement (if its status is New)
  rpc Remove(RemoveRequest) returns (google.protobuf.Empty);
  // Update estimated delivery date
  rpc SetDeliveryDate(SetDeliveryDateRequest) returns (ProcurementObject);
  // Set reference
  rpc SetReference(SetReferenceRequest) returns (ProcurementObject);
  // Add new SKU, update SKU, remove SKU
  rpc AddSku(AddSkuRequest) returns (ProcurementObject);
  // Remove SKU
  rpc RemoveSku(RemoveSkuRequest) returns (ProcurementObject);
  // Set piece
  rpc SetSkuPiece(SetSkuPieceRequest) returns (ProcurementObject);
  // Set price
  rpc SetSkuPrice(SetSkuPriceRequest) returns (ProcurementObject);
  // Add UPL candidate to procurement
  // Here we need to check if UPL is not already in use!
  rpc AddUpl(AddUplRequest) returns (ProcurementObject);
  // Update UPL candidate
  // e.g. correct bulk piece or best_before date
  rpc UpdateUpl(UpdateUplRequest) returns (ProcurementObject);
  // Remove UPL candidate from procurement
  // e.g. upl ID has scanned into a wrong SKU
  rpc RemoveUpl(RemoveUplRequest) returns (ProcurementObject);
  // Set Status
  rpc SetStatus(SetStatusRequest) returns (ProcurementObject);
}

message e {}

message GetInfoBulkRequest { repeated uint32 procurement_ids = 1; }

message GetByIdRequest { uint32 procurement_id = 1; }

message ProcurementIds { repeated uint32 procurement_ids = 1; }

message RemoveRequest { uint32 procurement_id = 1; }

message GetStatBySkuRequest { uint32 sku = 1; }

message StatResponse {
  string date_rfc3339 = 1;
  uint32 piece = 2;
  uint32 net_wholesale_price = 3;
}

message SetDeliveryDateRequest {
  uint32 procurement_id = 1;
  // RFC3339
  string delivery_date = 2;
}

message SetReferenceRequest {
  uint32 procurement_id = 1;
  string reference = 2;
}

message ProcurementItem {
  uint32 sku = 1;
  uint32 ordered_amount = 2;
  uint32 expected_net_price = 3;
}

message UplCandidate {
  // UPL ID
  string upl_id = 1;
  // Related SKU
  uint32 sku = 2;
  // UPL piece; if bulk, than bigger then 1
  uint32 upl_piece = 3;
  // False if SKU or Bulk SKU
  // True if opened SKU
  bool opened_sku = 4;
  // Best before, if there is any
  // RFC3339
  string best_before = 5;
}

message AddSkuRequest {
  uint32 procurement_id = 1;
  ProcurementItem sku = 2;
}

message RemoveSkuRequest {
  uint32 procurement_id = 1;
  uint32 sku = 2;
}

message SetSkuPieceRequest {
  uint32 procurement_id = 1;
  uint32 sku = 2;
  uint32 piece = 3;
}

message SetSkuPriceRequest {
  uint32 procurement_id = 1;
  uint32 sku = 2;
  uint32 expected_net_price = 3;
}

message AddUplRequest {
  uint32 procurement_id = 1;
  UplCandidate upl_candidate = 2;
}

message UpdateUplRequest {
  uint32 procurement_id = 1;
  string upl_id = 2;
  uint32 sku = 3;
  uint32 piece = 4;
  string best_before = 5;
}

message RemoveUplRequest {
  uint32 procurement_id = 1;
  string upl_id = 2;
}

enum Status {
  New = 0;
  Ordered = 1;
  Arrived = 2;
  Processing = 3;
  Closed = 4;
}

message SetStatusRequest {
  uint32 procurement_id = 1;
  Status status = 2;
  uint32 created_by = 3;
}

message CreateNewRequest {
  // This source should be verified
  uint32 source_id = 1;
  uint32 created_by = 3;
}

message ProcurementObject {
  // Procurement ID
  uint32 id = 1;
  // Source ID; only one source per procurement allowed
  uint32 source_id = 2;
  // Related document reference ID
  string reference = 3;
  // RFC3339
  string estimated_delivery_date = 10;
  repeated ProcurementItem items = 4;
  repeated UplCandidate upls = 5;
  Status status = 6;
  string created_at = 7;
  uint32 created_by = 8;
}

message ProcurementInfoObject {
  // Procurement ID
  uint32 id = 1;
  uint32 source_id = 2;
  uint32 sku_count = 3;
  uint32 sku_piece_count = 4;
  uint32 upl_count = 5;
  string estimated_delivery_date = 6;
  Status status = 7;
  string created_at = 8;
  uint32 created_by = 9;
}