Merge pull request #24 from Pup-Ion-Dev/item-status

Item status
This commit is contained in:
Drew Rautenberg
2025-01-24 12:35:13 -06:00
committed by GitHub
10 changed files with 206 additions and 37 deletions
@@ -11,8 +11,8 @@ using barkmanapi;
namespace barkmanapi.Migrations namespace barkmanapi.Migrations
{ {
[DbContext(typeof(BarkContext))] [DbContext(typeof(BarkContext))]
[Migration("20250122011527_postyFirst")] [Migration("20250124040847_status")]
partial class postyFirst partial class status
{ {
/// <inheritdoc /> /// <inheritdoc />
protected override void BuildTargetModel(ModelBuilder modelBuilder) protected override void BuildTargetModel(ModelBuilder modelBuilder)
@@ -59,15 +59,50 @@ namespace barkmanapi.Migrations
.HasColumnType("text") .HasColumnType("text")
.HasColumnName("serial_number"); .HasColumnName("serial_number");
b.Property<string>("Status") b.Property<string>("StatusId")
.HasColumnType("text") .HasColumnType("text")
.HasColumnName("status"); .HasColumnName("status_id");
b.HasKey("Id") b.HasKey("Id")
.HasName("pk_inventory"); .HasName("pk_inventory");
b.HasIndex("StatusId")
.HasDatabaseName("ix_inventory_status_id");
b.ToTable("inventory", (string)null); b.ToTable("inventory", (string)null);
}); });
modelBuilder.Entity("barkmanapi.ItemStatus", b =>
{
b.Property<string>("Id")
.HasColumnType("text")
.HasColumnName("id");
b.Property<string>("Name")
.IsRequired()
.HasColumnType("text")
.HasColumnName("name");
b.HasKey("Id")
.HasName("pk_item_status");
b.ToTable("item_status", (string)null);
});
modelBuilder.Entity("barkmanapi.InventoryItems", b =>
{
b.HasOne("barkmanapi.ItemStatus", "Status")
.WithMany("Items")
.HasForeignKey("StatusId")
.HasConstraintName("fk_inventory_item_status_status_id");
b.Navigation("Status");
});
modelBuilder.Entity("barkmanapi.ItemStatus", b =>
{
b.Navigation("Items");
});
#pragma warning restore 612, 618 #pragma warning restore 612, 618
} }
} }
@@ -6,11 +6,23 @@ using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata;
namespace barkmanapi.Migrations namespace barkmanapi.Migrations
{ {
/// <inheritdoc /> /// <inheritdoc />
public partial class postyFirst : Migration public partial class status : Migration
{ {
/// <inheritdoc /> /// <inheritdoc />
protected override void Up(MigrationBuilder migrationBuilder) protected override void Up(MigrationBuilder migrationBuilder)
{ {
migrationBuilder.CreateTable(
name: "item_status",
columns: table => new
{
id = table.Column<string>(type: "text", nullable: false),
name = table.Column<string>(type: "text", nullable: false)
},
constraints: table =>
{
table.PrimaryKey("pk_item_status", x => x.id);
});
migrationBuilder.CreateTable( migrationBuilder.CreateTable(
name: "inventory", name: "inventory",
columns: table => new columns: table => new
@@ -20,7 +32,7 @@ namespace barkmanapi.Migrations
name = table.Column<string>(type: "text", nullable: false), name = table.Column<string>(type: "text", nullable: false),
brand = table.Column<string>(type: "text", nullable: false), brand = table.Column<string>(type: "text", nullable: false),
serial_number = table.Column<string>(type: "text", nullable: true), serial_number = table.Column<string>(type: "text", nullable: true),
status = table.Column<string>(type: "text", nullable: true), status_id = table.Column<string>(type: "text", nullable: true),
rental_price = table.Column<float>(type: "real", nullable: true), rental_price = table.Column<float>(type: "real", nullable: true),
replacement_cost = table.Column<float>(type: "real", nullable: true), replacement_cost = table.Column<float>(type: "real", nullable: true),
notes = table.Column<string>(type: "text", nullable: true) notes = table.Column<string>(type: "text", nullable: true)
@@ -28,7 +40,17 @@ namespace barkmanapi.Migrations
constraints: table => constraints: table =>
{ {
table.PrimaryKey("pk_inventory", x => x.id); table.PrimaryKey("pk_inventory", x => x.id);
table.ForeignKey(
name: "fk_inventory_item_status_status_id",
column: x => x.status_id,
principalTable: "item_status",
principalColumn: "id");
}); });
migrationBuilder.CreateIndex(
name: "ix_inventory_status_id",
table: "inventory",
column: "status_id");
} }
/// <inheritdoc /> /// <inheritdoc />
@@ -36,6 +58,9 @@ namespace barkmanapi.Migrations
{ {
migrationBuilder.DropTable( migrationBuilder.DropTable(
name: "inventory"); name: "inventory");
migrationBuilder.DropTable(
name: "item_status");
} }
} }
} }
@@ -56,15 +56,45 @@ namespace barkmanapi.Migrations
.HasColumnType("text") .HasColumnType("text")
.HasColumnName("serial_number"); .HasColumnName("serial_number");
b.Property<string>("Status") b.Property<string>("StatusId")
.HasColumnType("text") .HasColumnType("text")
.HasColumnName("status"); .HasColumnName("status_id");
b.HasKey("Id") b.HasKey("Id")
.HasName("pk_inventory"); .HasName("pk_inventory");
b.HasIndex("StatusId")
.HasDatabaseName("ix_inventory_status_id");
b.ToTable("inventory", (string)null); b.ToTable("inventory", (string)null);
}); });
modelBuilder.Entity("barkmanapi.ItemStatus", b =>
{
b.Property<string>("Id")
.HasColumnType("text")
.HasColumnName("id");
b.Property<string>("Name")
.IsRequired()
.HasColumnType("text")
.HasColumnName("name");
b.HasKey("Id")
.HasName("pk_item_status");
b.ToTable("item_status", (string)null);
});
modelBuilder.Entity("barkmanapi.InventoryItems", b =>
{
b.HasOne("barkmanapi.ItemStatus", "Status")
.WithMany()
.HasForeignKey("StatusId")
.HasConstraintName("fk_inventory_item_status_status_id");
b.Navigation("Status");
});
#pragma warning restore 612, 618 #pragma warning restore 612, 618
} }
} }
+87 -22
View File
@@ -8,56 +8,70 @@ var allowSpecificOrigins = "_AllowSpecificOrigins";
builder.Services.AddDbContext<BarkContext>(); builder.Services.AddDbContext<BarkContext>();
builder.Services.AddEndpointsApiExplorer(); builder.Services.AddEndpointsApiExplorer();
builder.Services.AddSwaggerGen(c => builder.Services.AddOpenApi("document", c =>
{ {
c.SwaggerDoc("v1", new OpenApiInfo { Title = "BarkMan API", Description = "BARK BARK WOOF WOOF", Version = "v1" }); c.AddDocumentTransformer((doc, _, _) =>
{
doc.Info.Version = "v1";
doc.Info.Title = "BarkMan API";
doc.Info.Description = "BARK BARK WOOF WOOF ARF";
return Task.CompletedTask;
});
}); });
builder.Services.AddCors(options => builder.Services.AddCors(options =>
{ {
options.AddPolicy(name: allowSpecificOrigins, options.AddPolicy(name: allowSpecificOrigins,
policy => policy =>
{ {
policy.WithOrigins("https://barkdev.ts.drewr.io", "http://localhost:5173").AllowAnyMethod().AllowAnyHeader(); policy.WithOrigins("https://barkdev.ts.drewr.io", "http://localhost:5173").AllowAnyMethod()
.AllowAnyHeader();
}); });
}); });
builder.Services.AddDbContext<BarkContext>(opt => builder.Services.AddDbContext<BarkContext>(opt =>
opt.UseNpgsql(builder.Configuration.GetConnectionString("DefaultConnection")).UseSnakeCaseNamingConvention()); opt.UseNpgsql(builder.Configuration.GetConnectionString("DefaultConnection")).UseSnakeCaseNamingConvention());
var app = builder.Build(); var app = builder.Build();
if (!app.Environment.IsProduction()) if (!app.Environment.IsProduction())
{ {
app.UseSwagger(); app.MapOpenApi();
app.UseSwaggerUI(c => app.UseSwaggerUI(c => { c.SwaggerEndpoint("/openapi/document.json", "Bark Productions API V1"); });
{
c.SwaggerEndpoint("/swagger/v1/swagger.json", "Bark Inventory API V1");
});
} }
app.MapGet("/", () => "Hello World!"); var inventoryGroup = app.MapGroup(prefix: "/inventory")
.WithTags("Inventory")
.WithDescription("Endpoints for managing inventory items");
app.MapGet("/inventory", async (BarkContext db) => var itemStatusGroup = app.MapGroup(prefix: "/itemstatus")
await db.Inventory.OrderBy(item=>item.Id).ToListAsync()); .WithTags("Item Status")
.WithDescription("Endpoints for managing item status");
app.MapGet("/inventory/{id}", async (int id, BarkContext db) => inventoryGroup.MapGet("", async (BarkContext db) =>
await db.Inventory.OrderBy(item => item.Id).ToListAsync());
inventoryGroup.MapGet("/{id}", async (int id, BarkContext db) =>
{ {
var item = await db.Inventory.FindAsync(id); var item = await db.Inventory
.Include(item => item.Status)
.FirstOrDefaultAsync(i => i.Id == id);
if (item == null) if (item == null)
{ {
return Results.NotFound(new { Message = "Inventory item not found" }); return Results.NotFound(new { Message = "Inventory item not found" });
} }
return Results.Ok(item); return Results.Ok(item);
}); });
app.MapPut("/inventory/{id}", async (int id, InventoryItems updatedItem, BarkContext db) => inventoryGroup.MapPut("/{id}", async (int id, InventoryItems updatedItem, BarkContext db) =>
{ {
var existingItem = await db.Inventory.FindAsync(id); var existingItem = await db.Inventory.FindAsync(id);
if (existingItem == null) if (existingItem == null)
{ {
return Results.NotFound(new { Message = "Inventory item not found" }); return Results.NotFound(new { Message = "Inventory item not found" });
} }
existingItem.Name = updatedItem.Name; existingItem.Name = updatedItem.Name;
existingItem.Brand = updatedItem.Brand; existingItem.Brand = updatedItem.Brand;
existingItem.SerialNumber = updatedItem.SerialNumber; existingItem.SerialNumber = updatedItem.SerialNumber;
@@ -68,27 +82,78 @@ app.MapPut("/inventory/{id}", async (int id, InventoryItems updatedItem, BarkCon
await db.SaveChangesAsync(); await db.SaveChangesAsync();
return Results.Ok(existingItem); return Results.Ok(existingItem);
}); });
app.MapPost("/inventory", async (InventoryItems newItem, BarkContext db) => inventoryGroup.MapPost("", async (InventoryItems newItem, BarkContext db) =>
{ {
db.Inventory.Add(newItem); db.Inventory.Add(newItem);
await db.SaveChangesAsync(); await db.SaveChangesAsync();
return Results.Created($"/inventory/{newItem.Id}", newItem); return Results.Created($"/inventory/{newItem.Id}", newItem);
}); });
app.MapDelete("/inventory/{id}", async (int id, BarkContext db) => inventoryGroup.MapDelete("/{id}", async (int id, BarkContext db) =>
{ {
var item = await db.Inventory.FindAsync(id); var item = await db.Inventory.FindAsync(id);
if (item == null) { if (item == null)
{
return Results.NotFound(new { Message = "Inventory item not found" }); return Results.NotFound(new { Message = "Inventory item not found" });
} }
db.Inventory.Remove(item); db.Inventory.Remove(item);
await db.SaveChangesAsync(); await db.SaveChangesAsync();
return Results.Ok(new { Message = "Inventory item deleted successfully" }); return Results.Ok(new { Message = "Inventory item deleted successfully" });
}); });
itemStatusGroup.MapGet("/", async (BarkContext db) =>
await db.ItemStatus.ToListAsync());
itemStatusGroup.MapPost("/", async (ItemStatus newItemStatus, BarkContext db) =>
{
db.ItemStatus.Add(newItemStatus);
await db.SaveChangesAsync();
return Results.Created($"/itemstatus/{newItemStatus.Id}", newItemStatus);
});
itemStatusGroup.MapGet("/{id}", async (string id, BarkContext db) =>
{
var itemStatus = await db.ItemStatus.FindAsync(id);
if (itemStatus == null)
{
return Results.NotFound(new { Message = "Item Status not found" });
}
return Results.Ok(itemStatus);
});
itemStatusGroup.MapPut("/{id}", async (string id, ItemStatus updatedStatus, BarkContext db) =>
{
var existingStatus = await db.ItemStatus.FindAsync(id);
if (existingStatus == null)
{
return Results.NotFound(new { Message = "Inventory item not found" });
}
existingStatus.Id = updatedStatus.Id;
existingStatus.Name = updatedStatus.Name;
await db.SaveChangesAsync();
return Results.Ok(existingStatus);
});
itemStatusGroup.MapDelete("/{id}", async (string id, BarkContext db) =>
{
var itemStatus = await db.ItemStatus.FindAsync(id);
if (itemStatus == null)
{
return Results.NotFound(new { Message = "Item status not found" });
}
db.ItemStatus.Remove(itemStatus);
await db.SaveChangesAsync();
return Results.Ok(new { Message = "Item status deleted successfully" });
});
using (var serviceScope = app.Services.CreateScope()) using (var serviceScope = app.Services.CreateScope())
{ {
var dbContext = serviceScope.ServiceProvider.GetRequiredService<BarkContext>(); var dbContext = serviceScope.ServiceProvider.GetRequiredService<BarkContext>();
@@ -97,4 +162,4 @@ using (var serviceScope = app.Services.CreateScope())
app.UseCors(allowSpecificOrigins); app.UseCors(allowSpecificOrigins);
app.Run(); app.Run();
+9 -1
View File
@@ -5,6 +5,7 @@ namespace barkmanapi;
public class BarkContext(DbContextOptions<BarkContext> options) : DbContext(options) public class BarkContext(DbContextOptions<BarkContext> options) : DbContext(options)
{ {
public DbSet<InventoryItems> Inventory { get; set; } public DbSet<InventoryItems> Inventory { get; set; }
public DbSet<ItemStatus> ItemStatus { get; set; }
} }
public class InventoryItems public class InventoryItems
@@ -13,8 +14,15 @@ public class InventoryItems
public string Name { get; set; } public string Name { get; set; }
public string Brand { get; set; } public string Brand { get; set; }
public string? SerialNumber { get; set; } public string? SerialNumber { get; set; }
public string? Status { get; set; } public ItemStatus Status { get; set; }
public string? StatusId { get; set; }
public float? RentalPrice { get; set; } public float? RentalPrice { get; set; }
public float? ReplacementCost { get; set; } public float? ReplacementCost { get; set; }
public string? Notes { get; set; } public string? Notes { get; set; }
}
public class ItemStatus
{
public string Id { get; set; }
public string Name { get; set; }
} }
+4
View File
@@ -19,4 +19,8 @@
<PackageReference Include="Swashbuckle.AspNetCore" Version="6.1.4" /> <PackageReference Include="Swashbuckle.AspNetCore" Version="6.1.4" />
</ItemGroup> </ItemGroup>
<ItemGroup>
<Folder Include="Migrations\" />
</ItemGroup>
</Project> </Project>
@@ -15,7 +15,8 @@ function EditItem() {
initialValues: { initialValues: {
name: "", name: "",
brand: "", brand: "",
status: "", statusId: "",
status: {name: "", id: ""},
serialNumber: "", serialNumber: "",
rentalPrice: 0, rentalPrice: 0,
replacementCost: 0, replacementCost: 0,
@@ -94,8 +95,8 @@ function EditItem() {
placeholder="Brand" {...editItemForm.getInputProps('brand')}/> placeholder="Brand" {...editItemForm.getInputProps('brand')}/>
<TextInput withAsterisk key={editItemForm.key('name')} size="md" label="Name" <TextInput withAsterisk key={editItemForm.key('name')} size="md" label="Name"
placeholder="Name" {...editItemForm.getInputProps('name')}/> placeholder="Name" {...editItemForm.getInputProps('name')}/>
<TextInput size="md" key={editItemForm.key('status')} label="Status" <TextInput size="md" key={editItemForm.key('statusId')} label="Status"
placeholder="Status" {...editItemForm.getInputProps('status')}/> placeholder="Status" {...editItemForm.getInputProps('statusId')}/>
<TextInput size="md" key={editItemForm.key('serialNumber')} label="Serial Number" <TextInput size="md" key={editItemForm.key('serialNumber')} label="Serial Number"
placeholder="Serial Number"{...editItemForm.getInputProps('serialNumber')}/> placeholder="Serial Number"{...editItemForm.getInputProps('serialNumber')}/>
<NumberInput size="md" key={editItemForm.key('rentalPrice')} label="Rental Price" <NumberInput size="md" key={editItemForm.key('rentalPrice')} label="Rental Price"
@@ -59,7 +59,7 @@ function InventoryList() {
<Table.Td>{data.id}</Table.Td> <Table.Td>{data.id}</Table.Td>
<Table.Td>{data.brand}</Table.Td> <Table.Td>{data.brand}</Table.Td>
<Table.Td>{data.name}</Table.Td> <Table.Td>{data.name}</Table.Td>
<Table.Td>{data.status}</Table.Td> <Table.Td>{data.statusId}</Table.Td>
<Table.Td> <Table.Td>
<Link to={`/itemDetail/${data.id}`}>Details</Link> <Link to={`/itemDetail/${data.id}`}>Details</Link>
</Table.Td> </Table.Td>
@@ -32,7 +32,7 @@ function ItemDetail() {
<Text>ID: {data.id}</Text> <Text>ID: {data.id}</Text>
<Text>Brand: {data.brand}</Text> <Text>Brand: {data.brand}</Text>
<Text>Name: {data.name}</Text> <Text>Name: {data.name}</Text>
<Text>Status: {data.status}</Text> <Text>Status: {data.status.name}</Text>
<Text>Serial Number: {data.serialNumber}</Text> <Text>Serial Number: {data.serialNumber}</Text>
<Text>Rental Price: ${data.rentalPrice}</Text> <Text>Rental Price: ${data.rentalPrice}</Text>
<Text>Replacement Cost: ${data.replacementCost}</Text> <Text>Replacement Cost: ${data.replacementCost}</Text>
+2 -1
View File
@@ -2,7 +2,8 @@ export interface InventoryItem {
id: number, id: number,
brand: string, brand: string,
name: string, name: string,
status: string, status: {id: string; name: string},
statusId: string;
serialNumber: string, serialNumber: string,
rentalPrice: number, rentalPrice: number,
replacementCost: number, replacementCost: number,