To make this control you need to have a field where you control which was the last user used. I suggest doing a normalization in your bank, changing the field periodo
passing the data to a table and storing only the ID of those records in the user table, and store in that table which was the last user used, so you will have a queue for each shift . Here's an example.
Basic modeling:
Shifts
CREATE TABLE 'turnos'(
id INT NOT NULL AUTO_INCREMENT PRIMARY KEY,
nome VARCHAR(45),
lastfunc INT
);
INSERT INTO turnos (nome) VALUES ('manhã'), ('tarde');
_________________________
| id | nome | lastfunc |
|____|_______|____________|
| 1 | manhã | |
|____|_______|____________|
| 2 | tarde | |
|____|_______|____________|
2 registros
The lastfunc
column will be used to control the user / employee sequence.
Employees
CREATE TABLE 'funcionarios'(
id INT NOT NULL AUTO_INCREMENT PRIMARY KEY,
nome VARCHAR(45),
turno_id INT NOT NULL,
FOREIGN KEY (turno_id) REFERENCES turnos(id)
);
INSERT INTO funcionarios (nome, turno_id) VALUES
('João', 1), ('Maria', 1), ('José', 2), ('Joana', 2);
__________________________
| id | nome | turno_id |
|____|__________|__________|
| 1 | João | 1 | ---
|____|__________|__________| |-- Turno da Manhã
| 2 | Maria | 1 | ---
|____|__________|__________|
| 3 | José | 2 | ---
|____|__________|__________| |-- Turno da Tarde
| 4 | Joana | 2 | ---
|____|__________|__________|
4 registros
Customers
CREATE TABLE 'clientes'(
id INT NOT NULL AUTO_INCREMENT PRIMARY KEY,
nome VARCHAR(45),
funcionario_id INT,
FOREIGN KEY (funcionario_id) REFERENCES funcionarios(id)
);
____________________________
| id | nome | funcionario_id |
|____|______|________________|
0 registro
Code and Logic.
The logic is that every time we register a customer, we look for an employee to associate with his / her account, the
Employee Search is as follows:
- If registered customer searches existing in the registry
- Otherwise if there is near the search queue based on the time
- If it does not exist next, fetch the first from the queue
Based on this rule, I built the following code: (Detail in comments)
// Altere CPF e Variável $turno para testes
$novoCliente = Array(
'cpf' => '66666666668',
'nome' => 'Fulano Pereira Pinto',
'funcionario_id' => null
);
$turno = 2; // 1 - Manhã | 2 - Tarde
// Define variável para armazenar funcionário
$funcId = null;
// Consulta se o cliente tem cadastro com base no CPF e pega o funcionário associado
$stmt = $con->prepare("SELECT funcionario_id FROM clientes WHERE cpf = :cpf");
// Executa a query
$stmt->execute( Array(':cpf' => $novoCliente['cpf']) );
// Verifica se teve resultado, se sim armazena ID do funcionário
if ($stmt->rowCount() > 0)
$funcId = $stmt->fetch(PDO::FETCH_ASSOC)['funcionario_id'];
// Se não tem cadastro
if (is_null($funcId)){
// Pega o próximo funcionario da sequencia com base no turno
// A query busca o funcionario que tem um ID MAIOR do que o ID que estiver
// na tabela de turno no campo 'lastfunc', ou seja o próximo
$sql = "SELECT fu.id as id
FROM funcionarios as fu
INNER JOIN turnos as tu ON tu.id = fu.turno_id
WHERE
fu.id > tu.lastfunc AND
fu.turno_id = :turno
ORDER BY fu.id ASC LIMIT 1";
$stmt = $con->prepare($sql);
$stmt->execute( [':turno' => $turno] ); // Executa a query
// Se teve resultado armazena o ID do funcionário
if ($stmt->rowCount() > 0)
$funcId = $stmt->fetch(PDO::FETCH_ASSOC)['id'];
}
// Se a regra anterior não teve resultado é porque
// chegou no último da fila e não tem próximo
// ou porque não tem nenhum id no campo 'lastfunc' da tabela 'turno'
// Então executa a regra seguinte
if (is_null($funcId)){
// Seleciona o primeiro funcionario
$sql = "SELECT id FROM funcionarios ORDER BY id ASC LIMIT 1";
$stmt = $con->prepare($sql);
$stmt->execute(); // Executa a query
// Se teve resultado armazena o ID do funcionário
if ($stmt->rowCount() > 0)
$funcId = $stmt->fetch(PDO::FETCH_ASSOC)['id'];
// Se não houver funcionar é porque não existe funcionário cadastrado
}
if (is_null($funcId)){
// Se não pegou nenhum funcionário interrompe a execução do código
exit('Erro: Nenhum funcionário pode ser associado ao cliente. Cadastro interrompido.');
} else {
// Se encontrou algum funcionário atualiza os dados do cliente
$novoCliente['funcionario_id'] = $funcId;
}
// Insere o funcionário no banco com os dados
$stmt = $con->prepare("INSERT INTO clientes (cpf, nome, funcionario_id) VALUES (:cpf, :nome, :funcionario)");
// Executa a query
$res = $stmt->execute(
Array(
':cpf' => $novoCliente['cpf'],
':nome' => $novoCliente['nome'],
':funcionario' => $novoCliente['funcionario_id']
)
);
if ($res){
// Essa parte é muito IMPORTANTE
// Tens que armazenar o ID do funcionário utilizado no turno dele,
// para que a fila ande, pois é com base nesse campo que verificamos a
// posição da fila e então pegamos o próximo.
$stmt = $con->prepare("UPDATE turnos SET lastfunc = :lfunc WHERE id = :turno");
$res = $stmt->execute(
Array(
':lfunc' => $funcId,
':turno' => $turno
)
);
}
echo $res ? 'Sucesso' : 'Erro';
Result
Note: The first record left without an employee ID because I forgot to update the variable $novoCliente['funcionario_id']
before the INSERT
of the client.