/**
* @file IntermediateStock.hpp
* @author The ARTIS Development Team
* See the AUTHORS or Authors.txt file
*/
/*
* ARTIS - the multimodeling and simulation environment
* This file is a part of the ARTIS environment
*
* Copyright (C) 2013-2023 ULCO http://www.univ-littoral.fr
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see .
*/
#ifndef ARTIS_FACTORY_STOCK_HPP
#define ARTIS_FACTORY_STOCK_HPP
#include "Base.hpp"
#include "ProductionOrder.hpp"
namespace artis::factory {
struct StockEntry {
unsigned int po_id;
unsigned int po_index;
unsigned int product_id;
unsigned int quantity;
StockEntry(unsigned int po_id = 0, unsigned int po_index = 0, unsigned int product_id = 0, unsigned int quantity = 0)
: po_id(po_id), po_index(po_index), product_id(product_id), quantity(quantity) {}
bool operator==(const StockEntry &other) const {
return po_id == other.po_id and po_index == other.po_index and product_id == other.product_id and
quantity == other.quantity;
}
std::string to_string() const {
return "StockEntry < " + std::to_string(po_id) + " | " + std::to_string(po_index) + " | " +
std::to_string(product_id) + " | " + std::to_string(quantity) + " >";
}
};
struct ProductDemand {
unsigned int po_id;
unsigned int po_index;
unsigned int product_id;
unsigned int quantity;
ProductDemand(unsigned int po_id = 0, unsigned int po_index = 0, unsigned int product_id = 0,
unsigned int quantity = 0)
: po_id(po_id), po_index(po_index), product_id(product_id), quantity(quantity) {}
bool operator==(const ProductDemand &other) const {
return po_id == other.po_id and po_index == other.po_index and product_id == other.product_id and
quantity == other.quantity;
}
std::string to_string() const {
return "ProductDemand < " + std::to_string(po_id) + " | " + std::to_string(po_index) + " | " +
std::to_string(product_id) + " | " + std::to_string(quantity) + " >";
}
};
struct StockAvailableResponse {
int po_id;
enum values {
AVAILABLE, NOT_AVAILABLE, NEW_AVAILABLE
} response;
StockAvailableResponse(unsigned int po_id = 0, values response = NOT_AVAILABLE)
: po_id(po_id), response(response) {}
bool operator==(const StockAvailableResponse &other) const {
return po_id == other.po_id and response == other.response;
}
std::string to_string() const {
return "StockAvailableResponse < " + std::to_string(po_id) + " | " +
(response == AVAILABLE ? "AVAILABLE" : (response == NOT_AVAILABLE ? "NOT AVAILABLE" : "NEW AVAILABLE")) + " >";
}
};
struct ProductResponse {
int product_id;
int po_id;
ProductResponse(int product_id = -1, int po_id = -1) : product_id(product_id), po_id(po_id) {}
bool operator==(const ProductResponse &other) const {
return product_id == other.product_id and po_id == other.po_id;
}
std::string to_string() const {
return "Response < " + std::to_string(product_id) + " | " + std::to_string(po_id) + " >";
}
};
struct StockParameters {
std::vector _in_machines;
std::vector _out_machines;
int _capacity; // if -1 then infinity
};
class Stock : public Dynamics {
public:
struct inputs {
enum values {
IN, IN_DEMAND = 1000, IN_STOCK_AVAILABLE = 2000
};
};
struct outputs {
enum values {
OUT = 1000, OUT_STOCK_AVAILABLE = 2000
};
};
struct vars {
enum values {
ENTRY_NUMBER
};
};
Stock(const std::string &name, const Context &context)
: Dynamics(name, context), _parameters(context.parameters()) {
input_port({inputs::IN, "in"});
for (const auto &m: _parameters._in_machines) {
output_port({outputs::OUT + m, "out_" + std::to_string(m)});
input_port({inputs::IN_DEMAND + m, "in_demand_" + std::to_string(m)});
}
for (const auto &m: _parameters._out_machines) {
output_port({outputs::OUT_STOCK_AVAILABLE + m, "out_stock_available_" + std::to_string(m)});
input_port({inputs::IN_STOCK_AVAILABLE + m, "in_stock_available_" + std::to_string(m)});
}
observables({{vars::ENTRY_NUMBER, "entry number"}});
}
~Stock() override = default;
void dint(const Time &t) override;
void dext(const Time &t, const Time &e, const Bag &bag) override;
void start(const Time &t) override;
Time ta(const Time &t) const override;
Bag lambda(const Time &t) const override;
artis::common::event::Value observe(const Time &t, unsigned int index) const override;
private:
struct Phase {
enum values {
WAIT,
SEND,
SEND_AVAILABLE
};
static std::string to_string(const values &value) {
switch (value) {
case WAIT:
return "WAIT";
case SEND:
return "SEND";
case SEND_AVAILABLE:
return "SEND AVAILABLE";
}
return "";
}
};
struct Entry {
Time _t;
unsigned int _po_id;
unsigned int _po_index;
unsigned int _product_id;
unsigned int _quantity;
};
struct AvailableDemand {
unsigned int _machine_id;
unsigned int _po_id;
bool _available;
};
StockParameters _parameters;
Phase::values _phase;
std::vector _entries;
std::vector> _demands;
std::vector _available_demands;
std::deque> _waiting_machine_ids; // pair(machine_id,po_id)
};
} // namespace artis::factory
#endif