Programação com Objectos/Projecto de Programação com Objectos/Enunciado do Projecto de 2026-2027 (rascunho): Difference between revisions

From Wiki**3

Root (talk | contribs)
Root (talk | contribs)
Line 618: Line 618:
== Menu de Gestão de Compras ==
== Menu de Gestão de Compras ==


Este menu apresenta as operações relacionadas com compras e entregas. A lista completa é a seguinte: [[#Efectuar compra|Efectuar compra]], [[#Mostrar compra|Mostrar compra]], [[#Mostrar compras|Mostrar compras]], [[#Mostrar entregas de uma compra|Mostrar entregas de uma compra]].
Este menu apresenta as operações relacionadas com compras e encomendas. A lista completa é a seguinte: [[#Efectuar compra|Efectuar compra]], [[#Mostrar compra|Mostrar compra]], [[#Mostrar compras|Mostrar compras]], [[#Mostrar encomendas de uma compra|Mostrar encomendas de uma compra]].


{{CVSCode|As etiquetas das opções deste menu estão definidas em '''erp.app.purchase.Label'''. Os métodos correspondentes às mensagens de diálogo para este menu estão definidos em '''erp.app.purchase.Prompt''' e '''erp.app.purchase.Message'''.}}
{{CVSCode|As etiquetas das opções deste menu estão definidas em '''erp. app.purchase.Label'''. Os métodos correspondentes aos pedidos deste menu estão definidos em '''erp.app.purchase.Prompt'''. As mensagens do  processo de compra pertencem ao [[#Menu de Cabaz|menu de cabaz]] ('''erp.app.basket.Message''').}}
{{CVSCode|Estes comandos já estão implementados nas classes da ''package'' '''erp.app.purchase''' (disponível no GIT), respectivamente: '''DoDoPurchase''', '''DoShowPurchase''', '''DoShowPurchases''', '''DoShowPurchaseDeliveries'''.}}
{{CVSCode|Estes comandos já estão implementados nas classes da ''package'' '''erp.app.purchase''' (disponível no GIT), respectivamente: '''DoDoPurchase''', '''DoShowPurchase''', '''DoShowPurchases''', '''DoShowPurchaseOrders'''.}}                  


=== Efectuar compra ===
=== Efectuar compra ===


No processo de efectuar uma compra, o sistema pede, primeiro, a identificação do cliente; de seguida, a identificação da empresa a que a compra é feita; e, finalmente, para cada linha, o identificador do produto e a quantidade pretendida ('''Prompt.productId()''' e '''Prompt.amountToBuy()'''). O processo de adição de linhas termina de acordo com a interacção definida no comando.
Esta opção não efectua, por si só, qualquer compra: abre o [[#Menu de Cabaz|menu de cabaz]] sobre o cabaz de um cliente numa empresa.


Se não houver exemplares suficientes de um produto para satisfazer a quantidade pretendida, deve ser apresentada a mensagem '''Message.notEnoughInventory()''' e essa linha não é adicionada. Concluída a compra, o ''stock'' dos produtos é decrementado, a empresa passa a seguir o cliente e são determinadas as entregas correspondentes. A data limite de chegada de cada entrega é comunicada através da mensagem '''Message.deliveryDate()'''.
São pedidos o identificador do cliente e o identificador da empresa. Se ambos existirem, é aberto o [[#Menu de Cabaz|Menu de Cabaz]] sobre o cabaz desse cliente nessa empresa (criado vazio, se ainda não existir).
 
Como o cabaz pertence ao cliente, sair do menu sem finalizar a compra preserva o seu conteúdo e as suas opções para uma visita posterior.


=== Mostrar compra ===
=== Mostrar compra ===


É pedido o identificador da compra. Na primeira linha apresenta-se a informação da compra; de seguida, apresentam-se as suas entregas '''em detalhe''' — cada entrega (identificador da compra e data de chegada) seguida da descrição completa de cada um dos seus produtos (o mesmo formato de [[#Mostrar produto|Mostrar produto]]). O formato é o seguinte:
É pedido o identificador da compra. Na primeira linha apresenta-se a informação da compra; de seguida, apresentam-se as suas encomendas '''em detalhe''' — o cabeçalho de cada encomenda (sem a lista de identificadores de produtos) seguido da descrição completa de cada um dos seus produtos, indentada com dois espaços. As encomendas são apresentadas por ordem crescente da data prevista de entrega e, em caso de empate, pelos identificadores dos produtos.
{{CollapsedCode|Formato de apresentação de uma compra (com entregas em detalhe)|
 
''id'' - ''idCliente'' - ''idEmpresa'' - ''data'' - ''preço total dos itens'' - ''sobretaxa de entrega'' - ''preço total''
{{CollapsedCode|Formato de apresentação de uma compra (com encomendas em detalhe)|                                                             ''id'' - ''idCliente'' - ''idEmpresa'' - ''data'' - ''preço total dos itens'' - ''custo das encomendas'' - ''custo total''
  ''idCompra'' - ''data de chegada''
  ''idCompra'' - ''descrição do transporte'' - ''data prevista de       entrega'' - ''custo''
  ''descrição de produto''
␣␣''descrição de produto''                                             ␣␣...                                                                 }}
  ...
 
}}
{{CollapsedCode|Exemplo de apresentação de uma compra|
{{CollapsedCode|Exemplos de apresentação de compras|
<syntaxhighlight lang="text">
<syntaxhighlight lang="text">
7 - 3 - 1 - 4 - 90 - 9 - 99
1 - 1 - 1 - 1 - 94 - 30 - 124
7 - 7
1 - CTT/EXPRESSO+EMBRULHO - 5 - 15
  1 - 18 - FABRICADO - Farinha - 15 - ALIMENTAR - Moageira Nacional; F-0091
   3 - NACIONAL - Camisa - VESTUARIO - 45 - 58 - 2 - 3
   3 - 2 - FABRICADO - Camisa - 45 - VESTUARIO - Confeccoes Sul; C-1120
1 - CTT/EXPRESSO+EMBRULHO - 6 - 15
7 - 12
   1 - NACIONAL - Farinha - ALIMENTAR - 15 - 15 - 3 - 171
   2 - 1 - IMPORTADO - Telemovel - 200 - ELECTRONICA - China - 30
</syntaxhighlight>
</syntaxhighlight>
}}
}}
Line 651: Line 651:
=== Mostrar compras ===
=== Mostrar compras ===


Apresenta informações sobre todas as compras, ordenando-as pelos seus identificadores. O formato é o descrito em [[#Mostrar compra|Mostrar compra]].
Apresenta informações sobre todas as compras, ordenando-as pelos seus identificadores, no [[#Formatos de Apresentação|formato de apresentação de uma compra]] (apenas a linha da compra, sem as encomendas).


=== Mostrar entregas de uma compra ===
=== Mostrar encomendas de uma compra ===


É pedido o identificador da compra e são apresentadas as entregas correspondentes, ordenadas pela data de chegada e, em caso de empate, pelos identificadores dos produtos. Ao contrário de [[#Mostrar compra|Mostrar compra]] (que apresenta as entregas em detalhe), aqui cada entrega é apresentada '''de forma resumida''' (uma linha, apenas com os identificadores dos produtos), de acordo com o seguinte formato:
É pedido o identificador da compra e são apresentadas as encomendas correspondentes, ordenadas pela data prevista de entrega e, em caso de empate, pelos identificadores dos produtos. Ao contrário de [[#Mostrar compra|Mostrar compra]] (que apresenta as encomendas em detalhe), aqui cada encomenda é apresentada '''de forma resumida''' (uma linha, terminada pela lista de identificadores dos seus produtos), no [[#Formatos de Apresentação|formato de apresentação resumida de uma encomenda]].
{{CollapsedCode|Formato de apresentação de uma entrega|
 
''idCompra'' - ''data de chegada'' - ''lista de identificadores de produtos''
{{CollapsedCode|Exemplo de apresentação de encomendas (compra do exemplo anterior)|
}}
{{CollapsedCode|Exemplos de apresentação de entregas (compra do exemplo da secção Entregas)|
<syntaxhighlight lang="text">
<syntaxhighlight lang="text">
7 - 7 - 1, 3
1 - CTT/EXPRESSO+EMBRULHO - 5 - 15 - 3
7 - 12 - 2
1 - CTT/EXPRESSO+EMBRULHO - 6 - 15 - 1
</syntaxhighlight>
</syntaxhighlight>
}}
}}

Revision as of 13:20, 26 August 2026

AVISOS - Avaliação em Época Normal

Esclarecimento de dúvidas:

  • Consultar sempre o corpo docente atempadamente: presencialmente ou através do endereço oficial da disciplina [1].
  • Não utilizar fontes de informação não oficialmente associadas ao corpo docente (podem colocar em causa a aprovação à disciplina).
  • Não são aceites justificações para violações destes conselhos: quaisquer consequências nefastas são da responsabilidade do aluno.

Requisitos para desenvolvimento, material de apoio e actualizações do enunciado (ver informação completa em Projecto de Programação com Objectos):

  • O material de apoio é de uso obrigatório e não pode ser alterado.
  • Verificar atempadamente (mínimo de 48 horas antes do final de cada prazo) os requisitos exigidos pelo processo de desenvolvimento.

Processo de avaliação (ver informação completa em Avaliação do Projecto):

  • Datas: 2026/10/16 12:00 (inicial); 2026/11/20 12:00 (intercalar); 2026/12/18 12:00 (final); 2026/12/18 (early bird) 2027/01/06 (normal) (teste prático).
  • Todas as entregas são cruciais para o bom desenvolvimento do projecto, sendo obrigatórias: a não realização de uma entrega implica a exclusão da avaliação do projecto e, por consequência, da avaliação da disciplina.
  • Verificar atempadamente (até 48 horas antes do final de cada prazo) os requisitos exigidos pelo processo de avaliação, incluindo a capacidade de acesso ao repositório.
  • Apenas se consideram para avaliação os projectos existentes no repositório oficial. Apenas se considera para avaliação o ramo 'master'.
  • Trabalhos não presentes no repositório no final do prazo têm classificação 0 (zero) (não são aceites outras formas de entrega). Não são admitidas justificações para atrasos em sincronizações do repositório. A indisponibilidade temporária do repositório ou de outros materiais, desde que inferior a 24 horas, não justifica atrasos na submissão de um trabalho.
  • A avaliação do projecto pressupõe o compromisso de honra de que o trabalho correspondente foi realizado pelos alunos correspondentes ao grupo de avaliação.
  • Fraudes na execução do projecto terão como resultado a exclusão dos alunos implicados do processo de avaliação.
Material de Uso Obrigatório
As bibliotecas po-uilib e o conteúdo inicial do repositório GIT são de uso obrigatório:
  • po-uilib (classes de base) po-uilib-202608310000.tar.bz2 (não pode ser alterada) - javadoc
  • erp-core (classes do "core") (via GIT) (deve ser completada -- os nomes das classes fornecidas não podem ser alterados)
  • erp-app (classes de interacção) (via GIT) (deve ser completada -- os nomes das classes fornecidas não podem ser alterados)
A máquina virtual, fornecida para desenvolvimento do projecto, já contém todo o material de apoio.
Uso Obrigatório: Repositório GIT
Apenas se consideram para avaliação os projectos existentes no repositório GIT oficial.

Trabalhos não presentes no repositório no final do prazo têm classificação 0 (zero) (não são aceites outras formas de entrega). Não são admitidas justificações para atrasos em sincronizações do repositório. A indisponibilidade temporária do repositório, desde que inferior a 24 horas, não justifica atrasos na submissão de um trabalho.

EM PREPARAÇÃO

ÉPOCA NORMAL

O objectivo do projecto é desenvolver um sistema de gestão de entregas rápidas de produtos (ERP — Express Retail Platform). O sistema deverá permitir, entre outras operações, (i) registar dados de empresas; (ii) registar dados de clientes; (iii) registar, gerir e pesquisar produtos; (iv) efectuar e gerir características de compras; (v) gerir as entregas correspondentes; e (vi) notificar os clientes sobre a situação das suas encomendas.

Neste texto, o tipo negrito indica um literal (i.e., é exactamente como apresentado); o símbolo ␣ indica um espaço; e o tipo itálico indica uma parte variável (i.e., uma descrição).

Conceitos e Relações do Modelo

Existem vários conceitos importantes neste contexto: empresas, produtos, clientes, transportadoras, cabazes, compras, encomendas e entregas.

Os conceitos listados não são os únicos possíveis no modelo e as suas relações (assim como relações com outros conceitos não mencionados) podem depender das escolhas do projecto.

Os clientes e os produtos são independentes das empresas: existem por si e podem relacionar-se com várias empresas. Cada empresa, no entanto, mantém registo dos clientes com quem interage, dos produtos que disponibiliza, das compras feitas e das encomendas que expede.

Uma compra representa a aquisição de produtos por um cliente a uma empresa, e resulta de finalizar um cabaz. Uma compra pode dar origem a uma ou mais encomendas, de acordo com a estratégia de divisão de encomendas utilizada.

Cada encomenda pode ser enviada através de uma determinada transportadora e pode incluir serviços adicionais que alteram o seu custo e/ou prazo de entrega.

Produtos

O sistema mantém um registo global de produtos. Cada produto é identificado por um número de produto. O identificador é atribuído automaticamente e incrementalmente (a partir de 1 ou do último valor atribuído, caso o estado do sistema tenha sido recuperado). Todos os produtos têm: um nome/descrição (cadeia de caracteres não vazia); um preço base (número inteiro positivo); uma categoria; e um prazo de entrega base (número inteiro de dias).

O preço base é uma propriedade intrínseca do produto e é definido ao nível do sistema. O preço base é independente das empresas que disponibilizam o produto. O preço base é uma propriedade intrínseca do produto e é definido ao nível do sistema. O preço base é independente das empresas que disponibilizam o produto. O sistema utiliza o preço base para calcular o preço recomendado do produto. O preço recomendado representa o valor de referência do produto no sistema. O seu cálculo pode depender do tipo de produto e de outras informações disponíveis no sistema.

Cada produto tem uma categoria, de acordo com a sua natureza. Inicialmente, consideram-se as seguintes categorias: (i) alimentar; (ii) electrónica; e (iii) vestuário. Deve ser possível adicionar novas categorias com impacto mínimo na aplicação já desenvolvida.

O produto existe independentemente das empresas que o disponibilizam. Assim, o mesmo produto pode ser disponibilizado por várias empresas, sendo possível que cada uma pratique um preço de venda diferente.

A informação relativa à disponibilização de um produto por uma empresa não deve ser considerada parte das características intrínsecas do produto.

Tipos de Produto

Todos os produtos considerados no sistema são fabricados, mas podem ter diferentes origens.

Inicialmente, consideram-se os seguintes tipos de produto:

  • produto nacional;
  • produto importado.

Um produto nacional possui apenas as propriedades gerais dos produtos.

Um produto importado possui, para além das propriedades gerais dos produtos:

  • um país de origem (cadeia de caracteres não vazia);
  • uma taxa alfandegária (número inteiro expressando uma percentagem);
  • um prazo de transporte internacional (número inteiro de dias).

O preço recomendado é calculado de forma diferente consoante o tipo de produto.

Deve ser possível introduzir novos tipos de produto com impacto mínimo na implementação desenvolvida.

Produtos Nacionais

Para um produto nacional, o preço recomendado depende do preço base e do número total de unidades actualmente disponíveis desse produto nas empresas que o disponibilizam.

Se o número total de unidades disponíveis for:

  • superior a 10000, o preço recomendado corresponde a 90% do preço base;
  • inferior a 100, o preço recomendado corresponde a 130% do preço base;
  • nos restantes casos, o preço recomendado corresponde ao preço base.

Por exemplo, considerando um produto nacional com preço base de 100 euros:

  • Unidades disponíveis = 50 => Preço recomendado = 130 euros;
  • Unidades disponíveis = 5000 => Preço recomendado = 100 euros;
  • Unidades disponíveis = 12000 => Preço recomendado = 90 euros.

Produtos Importados

Para um produto importado, o preço recomendado corresponde ao preço base acrescido da taxa alfandegária.

Se a taxa alfandegária for t%, o preço recomendado é calculado de acordo com:

preço base × (100 + t) / 100

Por exemplo, considerando um produto importado com preço base de 100 euros e uma taxa alfandegária de 20%, o preço recomendado será:

100 × (100 + 20) / 100 = 120 euros

O cálculo do preço recomendado deve ser realizado de forma polimórfica, de modo a que o código que utiliza produtos não tenha de conhecer explicitamente o tipo concreto de cada produto.

Empresas

O sistema mantém um registo das empresas que operam na plataforma. Cada empresa é identificada por um número de empresa. O identificador é atribuído automaticamente e incrementalmente (a partir de 1 ou do último valor atribuído, caso o estado do sistema tenha sido recuperado). Cada empresa tem ainda um nome (cadeia de caracteres não vazia).

Uma empresa pode disponibilizar vários produtos e cada produto pode ser disponibilizado por várias empresas.

Para cada produto que disponibiliza, a empresa deve manter informação sobre:

  • número de unidades disponíveis (valor inteiro);
  • factor multiplicativo do preço recomendado (número positivo).

O número de unidades disponíveis e o factor multiplicativo podem ser diferentes para cada empresa que disponibiliza o mesmo produto.

O factor multiplicativo permite que uma empresa pratique um preço de venda diferente do preço recomendado pelo sistema. O preço de venda de um produto pela empresa é calculado multiplicando o preço recomendado do produto pelo factor multiplicativo definido pela empresa. Assim, duas empresas podem disponibilizar o mesmo produto a preços diferentes e com quantidades diferentes em stock.

Por exemplo, o produto P1, com um preço recomendado de 100 euros, pode ser disponibilizado pela empresa A com um preço de 90 euros, através de um factor multiplicativo de 0,9. A empresa B pode disponibilizar o mesmo produto com um preço de 120 euros, através de um factor multiplicativo de 1,2.

Deve ser possível adicionar outras propriedades às empresas sem impacto significativo no código já desenvolvido.

Clientes

O sistema mantém um registo de clientes. Cada cliente é identificado por um número de cliente. O identificador é atribuído automaticamente e incrementalmente (a partir de 1 ou do último valor atribuído, caso o estado do sistema tenha sido recuperado). Cada cliente tem ainda informação sobre o seu nome e endereço de correio electrónico. Estes campos não podem ser vazios.

Assume-se que os clientes têm sempre dinheiro, i.e., uma compra nunca é recusada por falta de fundos.

Compras

O sistema regista as compras efectuadas pelos clientes. Cada compra é identificada por um número de compra, atribuído automaticamente e incrementalmente. Uma compra é sempre feita por um único cliente a uma única empresa numa determinada data.

Uma compra é constituída por um conjunto de linhas (um "cabaz"). Cada linha corresponde a:

  • um produto;
  • uma quantidade (número de exemplares adquiridos desse produto);
  • um preço unitário (o preço de venda do produto pela empresa no momento da compra);
  • um preço total da linha (quantidade × preço unitário).

O preço unitário utilizado numa compra deve ser guardado na própria linha da compra. Alterações posteriores ao preço base, ao preço recomendado, ao factor multiplicativo da empresa, ou a qualquer outra propriedade utilizada no cálculo do preço, não devem alterar o valor de compras já efectuadas.

O preço total dos itens de uma compra é a soma dos preços totais das suas linhas. Uma compra pode dar origem a uma ou mais encomendas, de acordo com uma estratégia de divisão de encomendas.

A divisão de uma compra em várias encomendas pode ter impacto no custo total da compra.

Cabaz de Compras

Antes de dar origem a uma compra, os produtos que um cliente pretende adquirir a uma empresa são acumulados num cabaz.

Cada cliente tem um cabaz por cada empresa em que compra. O cabaz é constituído por um conjunto de linhas; cada linha corresponde a um produto disponibilizado por essa empresa e a uma quantidade. Acrescentar ao cabaz um produto que já lá esteja acumula as quantidades.

O cabaz regista ainda as opções que serão aplicadas à compra:

A transportadora, a modalidade e os serviços adicionais escolhidos aplicam-se a todas as encomendas resultantes da compra.

Enquanto não for finalizado, o cabaz não tem qualquer efeito no resto do sistema: em particular, não reserva nem consome inventário, e os preços apresentados são sempre os preços de venda praticados pela empresa nesse momento. Um cabaz faz parte do estado persistente da aplicação: pode ser abandonado e retomado mais tarde.

Ao finalizar o cabaz, e apenas nesse momento:

  • os preços de venda são fixados nas linhas da compra;
  • a compra é dividida em encomendas de acordo com a estratégia registada no cabaz;
  • todas as encomendas recebem a modalidade de transporte e os serviços adicionais registados no cabaz;
  • o inventário dos produtos na empresa é decrementado e o cliente é debitado;
  • o cabaz fica vazio.

Um cabaz vazio não pode ser finalizado, nem o pode ser um cabaz em que ainda não tenham sido escolhidas transportadora e modalidade. Se, no momento de finalizar, a empresa já não tiver exemplares suficientes de algum dos produtos do cabaz (por exemplo, porque o inventário foi entretanto alterado), a operação falha sem qualquer efeito e o cabaz mantém-se intacto.

Divisão das Compras em Encomendas

Cada encomenda tem um custo base de processamento e expedição, de 5 euros. Assim, uma compra dividida em várias encomendas pode ter um custo superior ao de uma compra enviada numa única encomenda.

O custo base associado às encomendas corresponde ao número de encomendas multiplicado pelo custo base de uma encomenda.

A este custo podem acrescer os custos associados ao método de transporte seleccionado e aos serviços adicionais.

O custo total de uma compra corresponde, assim, ao custo dos produtos acrescido:

  • do custo base das encomendas;
  • dos custos adicionais das tarifas de transporte;
  • dos custos dos serviços adicionais seleccionados.

A forma como uma compra é dividida em encomendas é determinada por uma estratégia de divisão de encomendas. Inicialmente, devem ser suportadas, pelo menos, as seguintes estratégias: encomenda única (UNICA) e agrupamento por prazo de entrega (PRAZO).

Encomenda única

Todos os produtos da compra são colocados numa única encomenda.

Neste caso, a compra origina uma única encomenda, independentemente dos prazos de entrega dos produtos.

Agrupamento por prazo de entrega

Os produtos são agrupados de acordo com os seus prazos de entrega.

Calcula-se a média dos prazos de entrega dos produtos das linhas da compra:

  • todas as linhas cujo produto tem prazo menor ou igual à média são agrupadas numa única encomenda;
  • cada linha cujo produto tem prazo estritamente maior do que a média é enviada separadamente, numa encomenda própria.

Por exemplo, considere-se uma compra com três linhas cujos produtos têm os prazos de entrega 3 (P1), 8 (P2) e 2 (P3). A média dos prazos é (3 + 8 + 2) / 3 ≈ 4,33. Logo, P1 e P3 (prazos ≤ 4,33) seguem juntos numa entrega e P2 (prazo > 4,33) segue numa outra encomenda:

  • Encomenda A: {P1, P3} (prazo = 3)
  • Encomenda B: {P2} (prazo = 8)

Uma estratégia de divisão que origina várias encomendas pode permitir que alguns produtos sejam entregues mais cedo, mas pode também resultar num custo superior devido ao custo associado a cada encomenda.

Deve ser possível introduzir novas estratégias de divisão de compras em encomendas com impacto mínimo na implementação desenvolvida.

Transportadoras

O sistema mantém um registo das transportadoras que operam na plataforma. Cada transportadora é identificada por um número de transportadora. O identificador é atribuído automaticamente e incrementalmente (a partir de 1 ou do último valor atribuído, caso o estado do sistema tenha sido recuperado). Cada transportadora tem ainda um nome (cadeia de caracteres não vazia).

Cada encomenda é enviada através de uma transportadora, segundo uma modalidade de transporte. Inicialmente, devem ser suportadas, pelo menos, as seguintes modalidades: normal (NORMAL) e expresso (EXPRESSO).

Uma modalidade não define, por si só, qualquer custo ou prazo: é apenas o nome de um nível de serviço. Para cada modalidade que oferece, uma transportadora define uma tarifa, constituída por:

  • um custo adicional (número inteiro); e
  • um tempo de transporte (número inteiro de dias).

Assim, a mesma modalidade pode custar e demorar valores diferentes consoante a transportadora.

Uma transportadora não tem de oferecer todas as modalidades: oferece exactamente aquelas para as quais tenha uma tarifa definida. Pedir a uma transportadora uma modalidade que ela não oferece é um erro, e não uma escolha silenciosamente ignorada — ver Definir modalidade de transporte.

Entre os dois, a transportadora tem precedência sobre a modalidade: como as modalidades disponíveis são as da transportadora, só se pode escolher uma modalidade depois de escolhida a transportadora, e mudar de transportadora anula a modalidade anteriormente escolhida (que passa a ser escolhida de novo, de entre as que a nova transportadora oferece).

Por exemplo:

Transportadora Modalidade Custo adicional Tempo de transporte
CTT NORMAL 3 euros 3 dias
CTT EXPRESSO 8 euros 1 dia
DHL NORMAL 5 euros 2 dias
DHL EXPRESSO 12 euros 1 dia
SEUR EXPRESSO 10 euros 1 dia

No exemplo acima, a transportadora SEUR só oferece a modalidade expresso: não é possível enviar por SEUR em modalidade normal.

A transportadora e a modalidade são escolhidas no cabaz e aplicam-se a todas as encomendas da compra; o modelo deve, no entanto, permitir que cada encomenda seja enviada por uma transportadora ou modalidade diferente.

A escolha da transportadora e da modalidade afecta tanto o custo como a data prevista de entrega da encomenda. Uma compra só pode ser finalizada depois de escolhidas ambas, e o par transportadora/modalidade de um cabaz é sempre um par que a transportadora oferece.

Deve ser possível introduzir novas modalidades de transporte com impacto mínimo na implementação desenvolvida. As transportadoras e as suas tarifas, por seu lado, fazem parte do estado da aplicação: são registadas pelo utilizador e não implicam qualquer alteração ao código.

Serviços Adicionais

O cliente pode seleccionar serviços adicionais, podendo aumentar o custo de cada encomenda, assim como o tempo necessário para a sua preparação e entrega. Os serviços são escolhidos no cabaz e aplicam-se a todas as encomendas da compra; o modelo deve, no entanto, permitir que cada encomenda tenha os seus próprios serviços.

Os serviços iniciais são os seguintes:

Serviço Chave Custo adicional Tempo adicional
Embrulho EMBRULHO 2 euros 1 dia
Cartão de oferta CARTAO_OFERTA 1 euro 0 dias

Os serviços adicionais podem ser combinados: uma encomenda pode incluir simultaneamente embrulho, cartão de oferta ou outro serviço adicional. O custo e o tempo adicionais de uma encomenda correspondem à soma dos contributos da modalidade de transporte e de todos os serviços seleccionados.

Deve ser possível introduzir novos serviços adicionais sem alterar o código das encomendas ou dos serviços já existentes.

Entregas

Cada encomenda tem uma data prevista de entrega. A data prevista de entrega é determinada considerando:

  • a data da compra;
  • os prazos de entrega dos produtos que constituem a encomenda;
  • o tempo de transporte da tarifa da transportadora seleccionada;
  • o tempo adicional introduzido pelos serviços seleccionados.

Para uma encomenda com vários produtos, o prazo dos produtos considerados para determinar a data prevista de entrega corresponde ao maior prazo de entrega dos seus produtos.

Não é necessário manter explicitamente um estado para representar se uma encomenda está ou não entregue. A situação da encomenda pode ser determinada a partir da data actual e da sua data prevista de entrega. Assim, uma encomenda é considerada entregue quando a data actual atinge ou ultrapassa a sua data prevista de entrega.

Gestão de Tempo

A unidade de tempo do sistema é o dia. A data do sistema começa no dia 1 (um) e faz parte do estado persistente.

A data do sistema pode ser avançada. Sempre que a data é alterada, devem ser verificadas as encomendas existentes para determinar:

  • quais as encomendas que serão entregues no dia seguinte;
  • quais as encomendas cuja data prevista de entrega foi atingida ou ultrapassada.

Quando a data actual atinge ou ultrapassa a data prevista de entrega de uma encomenda, esta considera-se entregue.

A gestão do tempo deve ainda desencadear notificações.

Pesquisas

Para permitir que os clientes determinem a existência de um produto, deverá ser possível efectuar pesquisas.

As pesquisas consideram os campos relevantes dos vários produtos, por exemplo, nome, categoria, tipo de produto ou país de origem.

O termo de pesquisa deve ser comparado sem distinção entre letras maiúsculas e minúsculas.

O sistema deve suportar diferentes critérios de pesquisa. Por exemplo, uma pesquisa pode procurar produtos cujo nome contenha determinado termo ou produtos pertencentes a determinada categoria.

Deve ser possível introduzir novos métodos de pesquisa de produtos com impacto mínimo na implementação desenvolvida.

Alterações de Inventário

O inventário de um produto numa empresa pode ser alterado através da especificação de um valor a somar ou subtrair ao número de exemplares disponíveis. Se a quantidade indicada for um valor positivo, aumenta-se o número de exemplares disponíveis. Se a quantidade indicada for um valor negativo, decrementa-se o número de exemplares disponíveis, desde que o número de exemplares disponíveis não fique negativo.

Um produto não é removido do sistema quando o seu inventário numa empresa chega a zero. Quando o inventário de um produto numa empresa chega a zero, o produto deixa de estar disponível nessa empresa, mas continua a existir no sistema e pode continuar a ser disponibilizado por outras empresas. Se o inventário de um produto numa empresa passar de zero para um valor positivo, o produto volta a estar disponível nessa empresa.

O número total de unidades disponíveis de um produto corresponde à soma dos inventários desse produto em todas as empresas que o disponibilizam.

Esta informação é utilizada, nomeadamente, no cálculo do preço recomendado dos produtos nacionais.

Notificações

O sistema deve notificar os clientes relativamente às suas encomendas.

Devem ser enviadas notificações em duas situações:

  • um dia antes da data prevista de entrega, informando o cliente de que a encomenda será entregue no dia seguinte;
  • no dia da entrega, informando o cliente de que a encomenda foi entregue.

Cada notificação deve ser enviada através do mecanismo de notificação seleccionado pelo cliente. Inicialmente, devem ser suportados, pelo menos, os seguintes mecanismos:

  • correio electrónico (EMAIL);
  • WhatsApp (WHATSAPP).

Cada cliente pode escolher o mecanismo através do qual pretende receber notificações do sistema. O mecanismo de notificação pode variar de cliente para cliente. Por exemplo, um cliente pode receber notificações por correio electrónico, enquanto outro pode recebê-las através de WhatsApp. Deve ser possível introduzir novos mecanismos de notificação sem necessidade de alterar o código dos clientes ou do sistema responsável por gerar as notificações.

Deve ser possível introduzir novos mecanismos de notificação com impacto mínimo na implementação desenvolvida.

As notificações devem ser enviadas pela ordem em que os acontecimentos ocorrem no sistema.

Requisitos de Desenho

A aplicação a desenvolver deve seguir o princípio de desenho aberto-fechado, por forma a aumentar a extensibilidade do seu código. Por exemplo, deve ser possível adicionar novos tipos de produto com um impacto mínimo no código já existente da aplicação.

Devem ser possíveis extensões ou alterações de funcionalidade com impacto mínimo no código já produzido para a aplicação. O objectivo é aumentar a flexibilidade da aplicação relativamente ao suporte de novas funções. Assim, deve ser possível:

  • Adicionar novos tipos de produto (e.g., produtos digitais ou perecíveis), incluindo a respectiva regra de cálculo do preço recomendado; * Adicionar novas categorias de produto;
  • Introduzir novas estratégias de divisão de compras em encomendas;
  • Introduzir novas modalidades de transporte (os custos e prazos de cada uma são dados de cada transportadora, não código; nem todas as transportadoras têm de oferecer todas as modalidades);
  • Introduzir novos serviços adicionais, sem alterar o código das encomendas nem o dos serviços já existentes;
  • Introduzir novos mecanismos de notificação, sem alterar o código dos clientes nem o do sistema que gera as notificações;
  • Introduzir novos critérios de discriminação/classificação dos clientes;
  • Introduzir novos critérios de pesquisa de produtos.

Funcionalidade da aplicação

A aplicação permite manter informação sobre as entidades do modelo, permitindo, em particular, gerir empresas, produtos, clientes e compras. Possui ainda a capacidade de preservar o seu estado (não é possível manter várias versões do estado da aplicação em simultâneo).

Nenhuma entidade é removida pelas operações descritas neste enunciado (em particular, um produto cujo inventário numa empresa chegue a zero continua a existir no sistema). Ainda assim, a aplicação deve estar preparada para que a remoção de qualquer entidade possa vir a ser suportada.

No início, a aplicação está vazia, mas pode ser carregada uma base de dados textual com conceitos pré-definidos. Neste caso, a aplicação começará com um estado referente às entidades que foram carregadas no arranque da aplicação.

Note-se que não é necessário implementar de raiz a aplicação: já existem classes que representam e definem a interface geral da funcionalidade do core da aplicação, tal como é visível pelos comandos da aplicação.
A interface geral do core já está parcialmente implementada na classe erp.ErpManager e outras fornecidas (cujos nomes devem ser mantidos), devendo ser adaptadas onde necessário. É ainda necessário criar e implementar as restantes classes que suportam a operação da aplicação.

Serialização

É possível guardar e recuperar o estado actual da aplicação, preservando toda a informação relacionada com o ERP e que foi descrita acima.

Após a recuperação do estado, os identificadores atribuídos a novas entidades devem continuar a ser atribuídos incrementalmente a partir do último valor utilizado em cada caso.

Interacção com o utilizador

Descreve-se nesta secção a funcionalidade máxima da interface com o utilizador. Em geral, os comandos pedem toda a informação antes de procederem à sua validação (excepto onde indicado). Todos os menus têm automaticamente a opção Sair (fecha o menu).

As operações de pedido e apresentação de informação ao utilizador devem realizar-se através dos objectos form e display, respectivamente, presentes em cada comando. As mensagens são produzidas pelos métodos das bibliotecas de suporte (po-uilib e erp-app). As mensagens não podem ser usadas no núcleo da aplicação (erp-core). Além disso, não podem ser definidas novas. Potenciais omissões devem ser esclarecidas antes de qualquer implementação.

De um modo geral, sempre que no contexto de uma operação com o utilizador aconteça alguma excepção, então a operação não deve ter qualquer efeito no estado da aplicação, excepto em caso de indicação contrária na operação em causa. As excepções estão na package erp.app.exceptions, excepto em caso de indicação contrária.

As excepções usadas na interacção (subclasses de pt.tecnico.uilib.menus.CommandException), excepto em caso de indicação contrária, são lançadas pelos comandos (subclasses de pt.tecnico.uilib.menus.Command) e tratadas pelos menus (instâncias de subclasses de pt.tecnico.uilib.menus.Menu). Outras excepções não devem substituir as fornecidas nos casos descritos.

Nos pedidos e usos dos vários identificadores, podem ocorrer as seguintes excepções, caso o identificador indicado não corresponda a um objecto conhecido (excepto no processo de registo ou em caso de indicação contrária). Note-se que estas excepções não são utilizáveis no núcleo da aplicação.

Tipo de dados Classe Pedido a apresentar Excepção a lançar se desconhecido
Empresa Company erp.app.company.Prompt.companyId() erp.app.exceptions.UnknownCompanyKeyException
Produto Product erp.app.product.Prompt.productId() erp.app.exceptions.UnknownProductKeyException
Cliente Client erp.app.client.Prompt.clientId() erp.app.exceptions.UnknownClientKeyException
Transportadora Carrier erp.app.carrier.Prompt.carrierId() erp.app.exceptions.UnknownCarrierKeyException
Compra Purchase erp.app.purchase.Prompt.purchaseId() erp.app.exceptions.UnknownPurchaseKeyException

Existe ainda um caso particular: sempre que uma operação se refira a um produto no contexto de uma empresa e essa empresa não disponibilize esse produto, deve ser lançada a excepção erp.app.exceptions.ProductNotSuppliedException (a empresa e o produto existem, mas não estão relacionados).

Alguns casos particulares podem usar pedidos específicos não apresentados nesta tabela.

Vários comandos pedem ao utilizador que escolha um valor de um conjunto fechado (tipo de produto, categoria, estratégia de divisão, modalidade de transporte, serviço adicional, mecanismo de notificação e critério de pesquisa). Estas escolhas devem ser pedidas através de campos de opção (Form.addOptionField() ou Form.requestOption()), sendo o conjunto de opções obtido do núcleo através da fachada. Desta forma, a introdução de uma nova estratégia, modalidade, serviço, mecanismo ou critério não implica qualquer alteração aos comandos.

Note-se que o programa principal e os comandos e menus, a seguir descritos, já estão parcial ou completamente implementados nas packages erp.app, erp.app.main, erp.app.company, erp.app.product, erp.app.client, erp.app.purchase. Estas classes são de uso obrigatório e estão disponíveis no GIT (módulo erp-app).

Formatos de Apresentação

Os formatos usados pelos vários comandos são os seguintes. Todos os campos são separados por ␣-␣.

Formato de apresentação de uma empresa
id - nome
Formato de apresentação de uma transportadora
id - nome
Formato de apresentação de uma tarifa
idTransportadora - modalidade - custo adicional - tempo  de transporte
Formato de apresentação de um produto
id - tipo - nome - categoria - preço base - preço recomendado - prazo base - unidades totais - informação adicional

O tipo é NACIONAL ou IMPORTADO. As unidades totais correspondem à soma dos inventários do produto em todas as empresas que o disponibilizam. Para produtos nacionais não existe informação adicional; para produtos importados, a informação adicional corresponde ao país de origem, à taxa alfandegária e ao prazo de transporte internacional.

Exemplos de apresentação de produtos
1 - NACIONAL - Farinha - ALIMENTAR - 15 - 15 - 3 - 173
2 - IMPORTADO - Telemovel - ELECTRONICA - 200 - 260 - 3 - 2 - China -   30 - 5
3 - NACIONAL - Camisa - VESTUARIO - 45 - 58 - 2 - 0
Formato de apresentação da disponibilização de um produto por uma empresa
 idEmpresa - idProduto - unidades - factor - preço de venda
Exemplos de apresentação de disponibilizações
2 - 1 - 150 - 0.9 - 14
2 - 2 - 2 - 1.2 - 312
Formato de apresentação de um cliente
id - nome - email - mecanismo de notificação - gasto total

O valor apresentado no fim corresponde ao total gasto pelo cliente em compras (um valor inteiro).

Exemplos de apresentação de clientes
2 - Ahsoka Tano - ahsoka@jedi.org - WHATSAPP - 0
1 - Obi-Wan Kenobi - obiwan@jedi.org - EMAIL - 124
Formato de apresentação de uma compra
id - idCliente - idEmpresa - data - preço total dos  itens - custo das encomendas - custo total
Formato de apresentação (resumida) de uma encomenda
idCompra - descrição do transporte - data prevista de entrega - custo - lista de identificadores de produtos

A descrição do transporte é o nome da transportadora e a modalidade seleccionadas, separados por /, seguidos das chaves dos serviços adicionais seleccionados, separadas por + (por exemplo, DHL/ EXPRESSO+EMBRULHO+CARTAO_OFERTA). O custo de uma encomenda é o custo base de processamento acrescido do custo da modalidade e dos serviços.

Exemplos de apresentação de encomendas
1 - CTT/EXPRESSO+EMBRULHO - 5 - 15 - 3
1 - CTT/EXPRESSO+EMBRULHO - 6 - 15 - 1

Menu Principal

As acções deste menu permitem gerir a salvaguarda do estado da aplicação e abrir submenus. A lista completa é a seguinte: Abrir, Guardar, Mostrar data actual, Avançar data actual, Menu de Gestão de Empresas, Menu de Gestão de Produtos, Menu de Gestão de Clientes e Menu de Gestão de Compras. Inicialmente, a aplicação apenas tem informação sobre as entidades que foram carregadas no arranque.

As etiquetas das opções deste menu estão definidas na classe erp.app.main.Label. Todos os métodos correspondentes às mensagens de diálogo para este menu estão definidos na classe erp.app.main.Message.
Estes comandos já estão implementados nas classes da package erp.app.main, respectivamente: DoOpenFile, DoSaveFile, DoDisplayDate, DoAdvanceDate, DoOpenMenuCompanies, DoOpenMenuProducts, DoOpenMenuClients, DoOpenMenuPurchases.

Salvaguarda do estado actual da aplicação

O conteúdo da aplicação (toda a informação detida pelo ERP actualmente em memória) pode ser guardado para posterior recuperação (via serialização Java: java.io.Serializable). Na leitura e escrita do estado da aplicação, devem ser tratadas as excepções associadas. A funcionalidade é a seguinte:

  • Abrir -- Carrega os dados de uma sessão anterior a partir de um ficheiro previamente guardado (ficando este ficheiro associado à aplicação, para futuras operações de salvaguarda). Pede-se o nome do ficheiro a abrir (Prompt.openFile()). Caso ocorra um problema na abertura ou processamento do ficheiro, deve ser lançada a excepção FileOpenFailedException. A execução bem-sucedida desta opção substitui toda a informação da aplicação.
    Quando se abandona uma aplicação com modificações não guardadas (porque se abre outra e existem alterações não guardadas), deve perguntar-se ao utilizador se quer guardar a informação actual antes de a abandonar, através de Prompt.saveBeforeExit() (a resposta é obtida via Form.confirm()).
  • Guardar -- Guarda o estado actual da aplicação no ficheiro associado. Se não existir associação, pede-se o nome do ficheiro a utilizar, ficando a ele associado (para operações de salvaguarda subsequentes). Esta interacção realiza-se através do método Prompt.newSaveAs(). Não é executada nenhuma acção se não existirem alterações desde a última salvaguarda.
Note-se que a opção Abrir não permite a leitura de ficheiros de texto (estes apenas podem ser utilizados no início da aplicação).
A opção Sair nunca implica a salvaguarda do estado da aplicação, mesmo que existam alterações.

Mostrar data actual

A data actual do sistema é apresentada através da mensagem Message.currentDate().

Avançar data actual

O número de dias a avançar é pedido através de Prompt.daysToAdvance(). O valor indicado deve ser positivo. Caso contrário, a operação não tem efeito.

Além da data, o sistema deve actualizar, caso seja necessário, outros aspectos que dela dependam, designadamente, a situação das entregas relativa às suas datas de chegada.

Gestão e consulta de dados da aplicação

  • Menu de Gestão de Empresas -- Abre o menu de gestão de empresas e operações associadas.
  • Menu de Gestão de Produtos -- Abre o menu de gestão de produtos e operações associadas.
  • Menu de Gestão de Clientes -- Abre o menu de gestão de clientes e operações associadas.
  • Menu de Gestão de Compras -- Abre o menu de gestão de compras e operações associadas.

Menu de Gestão de Empresas

Este menu permite efectuar operações sobre a base de dados de empresas. A lista completa é a seguinte: Registar empresa, Mostrar empresa, Mostrar empresas, Mostrar produtos de uma empresa, Mostrar clientes de uma empresa.

As etiquetas das opções deste menu estão definidas em erp.app.company.Label. Os métodos correspondentes às mensagens de diálogo para este menu estão definidos em erp.app.company.Prompt e erp.app.company.Message.

Registar empresa

Pede o nome (Prompt.companyName()). O registo bem sucedido é assinalado através da mensagem Message.registrationSuccessful(); caso contrário, é lançada a excepção CompanyRegistrationFailedException.

Note-se que a atribuição do identificador da empresa é automática.

Mostrar empresa

É pedido o identificador da empresa, sendo apresentadas as informações sobre essa empresa, de acordo com o seguinte formato:

Formato de apresentação de uma empresa
id - nome

Mostrar empresas

Apresenta informações sobre todas as empresas, ordenando-as pelos seus identificadores. O formato é o descrito em Mostrar empresa.

Mostrar produtos de uma empresa

É pedido o identificador da empresa e apresentam-se os produtos que essa empresa vende, ordenados pelos seus identificadores, utilizando o formato descrito em Mostrar produto.

Mostrar clientes de uma empresa

É pedido o identificador da empresa e apresentam-se os clientes que já interagiram com essa empresa, ordenados pelos seus identificadores, utilizando o formato descrito em Mostrar cliente.

Menu de Gestão de Produtos

Este menu apresenta as operações disponíveis sobre produtos. A lista completa é a seguinte: Mostrar produto, Mostrar produtos, Alterar inventário de um produto e Efectuar pesquisa.

As etiquetas das opções deste menu estão definidas em erp.app.product.Label. Os métodos correspondentes às mensagens de diálogo para este menu estão definidos em erp.app.product.Prompt e erp.app.product.Message.
Estes comandos já estão implementados nas classes da package erp.app.product (disponível no GIT), respectivamente: DoShowProduct, DoShowProducts, DoChangeProductInventory, DoPerformSearch.

Mostrar produto

É pedido o identificador do produto. Se o produto existir, é apresentado de acordo com o seguinte formato. O formato genérico de apresentação de um produto é como se segue:

Formato de apresentação de produtos
id - stock - tipo - nome - preço - categoria - informação adicional

Para produtos fabricados, a informação adicional corresponde ao nome do fabricante e ao código de fabrico (separados pelo carácter ;); para produtos importados, a informação adicional corresponde ao país de origem e à taxa alfandegária.

Exemplos de apresentação de produtos
3 - 20 - FABRICADO - Farinha - 15 - ALIMENTAR - Moageira Nacional; F-0091
4 - 2 - IMPORTADO - Telemóvel - 200 - ELECTRONICA - China - 30
5 - 0 - FABRICADO - Camisa - 45 - VESTUARIO - Confeccoes Sul; C-1120

Mostrar produtos

Apresenta informações sobre todos os produtos, ordenando-os pelos seus identificadores. O formato de apresentação é como descrito em Mostrar produto.

Alterar inventário de um produto

É pedido o identificador de um produto e uma quantidade (Prompt.amountToUpdate()) e actualizado o número de exemplares disponíveis do produto indicado somando a quantidade indicada ao número de exemplares disponíveis. No caso de não ser possível actualizar o número de exemplares devido ao facto de a quantidade indicada ser inválida, então a operação não deve ter qualquer efeito e deve ser apresentada a mensagem Message.notEnoughInventory().

Efectuar pesquisa

Esta opção realiza uma procura por termo (cadeia de caracteres), pedido através de Prompt.searchTerm(). Como resultado, deve ser apresentada uma lista dos produtos encontrados pela pesquisa, ordenados por ordem crescente do seu identificador, utilizando o formato descrito para Mostrar produto.

O termo de pesquisa deve ser comparado (sem distinção entre letras maiúsculas e minúsculas) com os campos relevantes de cada produto: o nome e a categoria. Só devem ser apresentados produtos que contenham o termo de pesquisa num dos campos relevantes. Caso não sejam encontrados produtos, não deve ser produzido qualquer resultado.

Menu de Gestão de Clientes

Este menu permite efectuar operações sobre a base de dados de clientes. A lista completa é a seguinte: Registar cliente, Mostrar cliente, Mostrar clientes, Mostrar notificações do cliente.

As etiquetas das opções deste menu estão definidas em erp.app.client.Label. Os métodos correspondentes às mensagens de diálogo para este menu estão definidos em erp.app.client.Prompt e erp.app.client.Message.

Registar cliente

Pede o nome (Prompt.clientName()) e o endereço de correio electrónico (Prompt.clientEMail()). O registo bem sucedido é assinalado através da mensagem Message.registrationSuccessful(); caso contrário, é lançada a excepção ClientRegistrationFailedException.

Note-se que a atribuição do identificador do cliente é automática e que clientes diferentes são registados em cada operação de registo.

Mostrar cliente

É pedido o identificador do cliente, sendo apresentadas as informações sobre esse cliente, de acordo com o seguinte formato. O valor apresentado após o email corresponde ao total gasto pelo cliente em compras (um valor inteiro).

Formato de apresentação de um cliente
id - nome - email - gasto total
Exemplos de apresentação de clientes
2 - Alberto Meireles - ameireles@mymail.com - 275
1 - Fernando Meireles - fmeireles@mymail.com - 0

Mostrar clientes

Apresenta informações sobre todos os clientes, ordenando-os lexicograficamente pelo nome. Caso existam clientes com o mesmo nome, devem ser ordenados por ordem crescente dos seus identificadores. O formato é o descrito em Mostrar cliente.

Mostrar notificações do cliente

É pedido o identificador do cliente, sendo apresentadas as notificações para esse cliente, de acordo com o seguinte formato:

Formato de apresentação das notificações de um cliente
DISPONIBILIDADE: descrição de produto disponível
Exemplos de notificações
DISPONIBILIDADE: 5 - 4 - FABRICADO - Camisa - 45 - VESTUARIO - Confeccoes Sul; C-1120

Note-se que a descrição é idêntica à que é realizada para mostrar cada produto. No entanto, a solução deve ser suficientemente flexível para permitir outros formatos de apresentação das notificações (sem impacto no código do domínio da aplicação).

Menu de Gestão de Compras

Este menu apresenta as operações relacionadas com compras e encomendas. A lista completa é a seguinte: Efectuar compra, Mostrar compra, Mostrar compras, Mostrar encomendas de uma compra.

As etiquetas das opções deste menu estão definidas em erp. app.purchase.Label. Os métodos correspondentes aos pedidos deste menu estão definidos em erp.app.purchase.Prompt. As mensagens do processo de compra pertencem ao menu de cabaz (erp.app.basket.Message).
Estes comandos já estão implementados nas classes da package erp.app.purchase (disponível no GIT), respectivamente: DoDoPurchase, DoShowPurchase, DoShowPurchases, DoShowPurchaseOrders.

Efectuar compra

Esta opção não efectua, por si só, qualquer compra: abre o menu de cabaz sobre o cabaz de um cliente numa empresa.

São pedidos o identificador do cliente e o identificador da empresa. Se ambos existirem, é aberto o Menu de Cabaz sobre o cabaz desse cliente nessa empresa (criado vazio, se ainda não existir).

Como o cabaz pertence ao cliente, sair do menu sem finalizar a compra preserva o seu conteúdo e as suas opções para uma visita posterior.

Mostrar compra

É pedido o identificador da compra. Na primeira linha apresenta-se a informação da compra; de seguida, apresentam-se as suas encomendas em detalhe — o cabeçalho de cada encomenda (sem a lista de identificadores de produtos) seguido da descrição completa de cada um dos seus produtos, indentada com dois espaços. As encomendas são apresentadas por ordem crescente da data prevista de entrega e, em caso de empate, pelos identificadores dos produtos.

Formato de apresentação de uma compra (com encomendas em detalhe)
id - idCliente - idEmpresa - data - preço total dos itens - custo das encomendas - custo total
idCompra - descrição do transporte - data prevista de        entrega - custo
␣␣descrição de produto                                              ␣␣...                                                                  
Exemplo de apresentação de uma compra
1 - 1 - 1 - 1 - 94 - 30 - 124
1 - CTT/EXPRESSO+EMBRULHO - 5 - 15
  3 - NACIONAL - Camisa - VESTUARIO - 45 - 58 - 2 - 3
1 - CTT/EXPRESSO+EMBRULHO - 6 - 15
  1 - NACIONAL - Farinha - ALIMENTAR - 15 - 15 - 3 - 171

Mostrar compras

Apresenta informações sobre todas as compras, ordenando-as pelos seus identificadores, no formato de apresentação de uma compra (apenas a linha da compra, sem as encomendas).

Mostrar encomendas de uma compra

É pedido o identificador da compra e são apresentadas as encomendas correspondentes, ordenadas pela data prevista de entrega e, em caso de empate, pelos identificadores dos produtos. Ao contrário de Mostrar compra (que apresenta as encomendas em detalhe), aqui cada encomenda é apresentada de forma resumida (uma linha, terminada pela lista de identificadores dos seus produtos), no formato de apresentação resumida de uma encomenda.

Exemplo de apresentação de encomendas (compra do exemplo anterior)
1 - CTT/EXPRESSO+EMBRULHO - 5 - 15 - 3
1 - CTT/EXPRESSO+EMBRULHO - 6 - 15 - 1

Leitura de Dados a Partir de Ficheiros Textuais

Além das opções de manipulação de ficheiros descritas no menu principal, é possível iniciar a aplicação com um ficheiro de texto especificado pela propriedade Java import.

Cada linha tem uma descrição distinta mas que segue o seguinte formato geral. É possível registar transportadoras, empresas, clientes e produtos, e definir as tarifas das transportadoras e as disponibilizações de produtos por parte das empresas. Assume-se que os campos de texto não podem conter o carácter : e que os preços são números inteiros. Não existem entradas mal-formadas.

O registo de transportadoras, e das tarifas que cada uma pratica, segue os formatos:

CARRIER:nome
RATE:idTransportadora:modalidade:custo:dias

As entradas RATE referem transportadoras já registadas em linhas anteriores. O registo de empresas e de clientes segue os formatos:

COMPANY:nome
CLIENT:nome:email
CLIENT:nome:email:mecanismo

O mecanismo é EMAIL ou WHATSAPP; se for omitido, assume-se EMAIL. Os produtos são registados no registo global, respectivamente para produtos nacionais e importados:

Os produtos são registados no registo global, respectivamente para produtos nacionais e importados:

NATIONAL:nome:preçoBase:categoria:prazo
IMPORTED:nome:preçoBase:categoria:prazo:paisOrigem:taxa:prazoInternacional

Note-se que o registo de um produto não indica qualquer empresa nem qualquer inventário: essas são propriedades da disponibilização, descrita por entradas próprias, em que unidades é o número de exemplares que a empresa tem disponíveis e factor o multiplicador (real) que aplica ao preço recomendado:

SUPPLY:idEmpresa:idProduto:unidades:factor

As entradas SUPPLY referem empresas e produtos já registados em linhas anteriores.

Um exemplo de conteúdo do ficheiro inicial é como se segue:

Exemplo de ficheiro de entrada textual
CARRIER:CTT
RATE:1:NORMAL:3:3
RATE:1:EXPRESSO:8:1
CARRIER:DHL
RATE:2:NORMAL:5:2
RATE:2:EXPRESSO:12:1
CARRIER:SEUR
RATE:3:EXPRESSO:10:1
COMPANY:Moageira Nacional
COMPANY:Importadora Atlantico
CLIENT:Obi-Wan Kenobi:obiwan@jedi.org
CLIENT:Ahsoka Tano:ahsoka@jedi.org:WHATSAPP
NATIONAL:Farinha:15:ALIMENTAR:3
IMPORTED:Telemovel:200:ELECTRONICA:3:China:30:5
NATIONAL:Camisa:45:VESTUARIO:2
SUPPLY:1:1:23:1.0
SUPPLY:2:1:150:0.9
SUPPLY:2:2:2:1.2
SUPPLY:1:3:4:1.1

A codificação dos ficheiros a ler é garantidamente UTF-8.

Os métodos String.split(), para partir cadeias de caracteres, e String.trim(), para remover espaços no início e no final, podem ser usados no processamento de cada linha.
Note-se que o programa nunca produz ficheiros com este formato (é apenas um formato para ficheiros de entrada).

Execução do Programa e Testes Automáticos

Usando os ficheiros test.import, test.in e test.out, é possível verificar automaticamente o resultado correcto do programa. Note-se que é necessária a definição apropriada da variável CLASSPATH (ou da opção equivalente -cp do comando java), para localizar as classes do programa, incluindo a que contém o método correspondente ao ponto de entrada da aplicação (erp.app.App.main). As propriedades são tratadas automaticamente pelo código de apoio.

 java -Dimport=test.import -Din=test.in -Dout=test.outhyp erp.app.App

Assumindo que aqueles ficheiros estão no directório onde é dado o comando de execução, o programa produz o ficheiro de saída test.outhyp. Em caso de sucesso, os ficheiros das saídas esperada (test.out) e obtida (test.outhyp) devem ser iguais. A comparação pode ser feita com o comando:

 diff -b test.out test.outhyp

Este comando não deve produzir qualquer resultado quando os ficheiros são iguais. Note-se, contudo, que este teste não garante o correcto funcionamento do código desenvolvido, apenas verificando alguns aspectos da sua funcionalidade.

Notas de Implementação

Tal como indicado acima, algumas classes fornecidas como material de apoio, são de uso obrigatório e não podem ser alteradas. Outras dessas classes são de uso obrigatório e têm de ser alteradas.

A serialização Java usa as classes da package java.io, em particular, a interface java.io. Serializable e as classes de leitura java.io.ObjectInputStream e escrita java.io.ObjectOutputStream (entre outras).