DEV Community

Yereka Ueh-kabari
Yereka Ueh-kabari

Posted on

Basic Store App using go.

Introduction:

This lesson will show you how to write a simple store application in the Go programming language. In the store, there is a product and a car as an example product, both of which are defined using structs, as well as methods for interacting with the store. A car's model, brand, year, color, condition, and mileage are all stored in the Car struct. The Product struct contains product information such as its ID, name, price, quantity, and status, as well as an embedding of the Car struct. The store struct keeps track of all the products in the store as well as all the products sold.

There are methods to interact with the store such as AddProduct, UpdateProduct, AddProducts, ListProducts, SellProduct, ListSoldProducts, and TotalSold.

  • The AddProduct method adds a new product to the store.
  • The UpdateProduct method updates an existing product in the store.
  • The AddProducts method adds multiple products to the store. - The ListProducts method returns a list of all products that are currently available for purchase in the store.
  • The SellProduct method allows you to sell a product and deduct the amount sold from the product's quantity. It also adds the sold item to the store's sold product list.
  • The ListSoldProducts method returns a list of all sold products as well as the total ProductPrice of all sold products.
  • The TotalSold method displays the total ProductPrice of all sold products.

Prerequisites:

  • A basic understanding of Go.
  • A Go runtime environment installation on the machine that will run it.
  • This lesson requires no additional packages or libraries other than the built-in fmt package. The code provided should work as is because the fmt package is used for input and output operations such as the Println function and others.

Let's Start Coding Step by Step:

Let's start by creating a package shop.go.
Inside the shop.go file that we created in the previous step, we start with the following starter code at the top of the file.

package shop

import "fmt"
Enter fullscreen mode Exit fullscreen mode

Define the car struct

type Car struct {
    Model   string
    Brand   string
    Year    int
    Color   string
    IsUsed  bool
    Mileage int
}
Enter fullscreen mode Exit fullscreen mode

We'd also define the Product struct which embeds the Car struct:

type Product struct {
    Id              int
    Name            string
    ProductPrice    float64
    ProductQuantity int
    ProductStatus   bool
    Car
}
Enter fullscreen mode Exit fullscreen mode

Define the store struct, which will hold slices of Product structs for products in the store and products that have been sold:

type store struct {
    products []Product
    sold     []Product
}
Enter fullscreen mode Exit fullscreen mode

Define a function NewShop which creates a new shop by returning a pointer to a store struct, this function is used as a constructor for the store struct:

func NewShop() *store {
    return &store{}
}
Enter fullscreen mode Exit fullscreen mode

Define a method updateStatus to update the ProductStatus field of the product struct:

func (p *Product) updateStatus(status bool) {
    p.ProductStatus = status
}
Enter fullscreen mode Exit fullscreen mode

Let's continue by adding all the methods necessary to make the store functional.

Add a method AddProduct to add a new product to the store, it takes a pointer to a Product struct as an argument and checks whether the product already exists and if so it updates the product:

func (s *store) AddProduct(p *Product) {
    //check if product already exists and update it
    for _, prod := range s.products {
        if prod.Name == p.Name {
            fmt.Println("Product already exists")
            fmt.Println("Updating product")
            s.UpdateProduct(p)
            return
        }
    }
    s.products = append(s.products, *p)
}
Enter fullscreen mode Exit fullscreen mode

Add a method UpdateProduct to update an existing product in the store, it takes a pointer to a Product struct as an argument and update the product with the same name as the input:

func (s *store) UpdateProduct(p *Product) {
    for i, prod := range s.products {
        if prod.Name == p.Name {
            s.products[i] = *p
            return
        }
    }
}
Enter fullscreen mode Exit fullscreen mode

Add a method AddProducts to add multiple products to the store, it takes a variable number of pointers to Product structs as arguments:

func (s *store) AddProducts(ps ...*Product) {
    for _, p := range ps {
        s.AddProduct(p)
    }
}
Enter fullscreen mode Exit fullscreen mode

Add a method ListProducts to list all products that are currently in the store and still for sale:

func (s *store) ListProducts() {
    //check if store has products
    if len(s.products) == 0 {
        fmt.Println("No products in store")    
    } else {
        fmt.Println("All Available Products:")

    for _, p := range s.products {
        p.Display()
    }
    fmt.Println("====================================")
    }
 }
Enter fullscreen mode Exit fullscreen mode

Add a method SellProduct to sell a product and reduce the product's quantity by the quantity sold. This method also add the sold item to the store's list of sold products:

func (s *store) SellProduct(id int, q int) {
    for i, p := range s.products {
    if p.Id == id {
        if p.ProductStatus {
            if p.ProductQuantity >= q {
                p.ProductQuantity -= q
                s.products[i] = p
                    s.checkSoldList(&p, q)
                } else {
                    fmt.Println("Not enough quantity")
                }
                // check if product quantity is 0, if yes, update product status to false
                if p.ProductQuantity == 0 {
                p.updateStatus(false)
                }
                return
            } else {
                fmt.Println("Product out of stock")
                return
            }
        }
    }
    fmt.Println("Product not found")
}
Enter fullscreen mode Exit fullscreen mode

Add a method checkSoldList to check if the sold list has a product, if yes, add the quantity sold to the product in the list else add the product and the quantity sold to the list:

func (s *store) checkSoldList(p *Product, q int) {
    for i, prod := range s.sold {
        if prod.Name == p.Name {
            s.sold[i].ProductQuantity += q
            return
        }
    }
    *p = Product{Id: p.Id, Name: p.Name, ProductPrice: p.ProductPrice, ProductQuantity: q}
    s.sold = append(s.sold, *p)
}
Enter fullscreen mode Exit fullscreen mode

Add a method ListSoldProducts to list all products that have been sold and also the total ProductPrice of all the products sold:

func (s *store) ListSoldProducts() {
    // check if store has products
    if len(s.sold) == 0 {
        fmt.Println("No products sold")
        return
    } else {
        fmt.Println("All Sold Products:")
        for _, p := range s.sold {
            fmt.Println(p.Name, "Quantity:", p.ProductQuantity)
        }
        fmt.Println("Total Sold:", s.TotalSold())
    }
}
Enter fullscreen mode Exit fullscreen mode

Add a method TotalSold to show the total ProductPrice of all products sold:

func (s *store) TotalSold() float64 {
    var total float64
    for _, p := range s.sold {
    total += p.ProductPrice * float64(p.ProductQuantity)
        }
        return total
}
Enter fullscreen mode Exit fullscreen mode

We also have a helper function Display to display things on the console for us so that we can see what's going on for now

func (p *Product) Display() {
    fmt.Printf("Product: %s, ProductPrice: %.2f, ProductQuantity: %d", p.Name, p.ProductPrice, p.ProductQuantity)
    fmt.Println()
}
Enter fullscreen mode Exit fullscreen mode

So that is the end of the shop package.

We'd quickly have a look at the main package to see how we call a new shop instance and run the methods
AddProduct,
UpdateProduct,
AddProducts,
ListProducts,
SellProduct,
ListSoldProducts,
and TotalSold.

We start by importing the necessary packages and then defining a main function.
In this case, we are importing the shop package we created earlier.
We are also importing the fmt package to use mostly in printing to the console.

package main
import (
    "fmt"

    "github.com/codeflames/AutoShopProject/shop"
)

func main() {
//create a new shop instance
shop1 := shop.NewShop()

}
Enter fullscreen mode Exit fullscreen mode

Inside the main function, we now create two new items/products (car product) that we can add to the shop we created earlier shop1.

You can create as much product you want here.


    item1 := &shop.Product{
        Id:              1,
        Name:            "Civic 2019",
        ProductPrice:    100.00,
        ProductQuantity: 10,
        ProductStatus:   true,
        Car: shop.Car{
            Model:   "Civic",
            Brand:   "Honda",
            Year:    2019,
            Color:   "Red",
            IsUsed:  false,
            Mileage: 0,
        },
    }

    item2 := &shop.Product{
        Id:              2,
        Name:            "Corolla 2018",
        ProductPrice:    200.00,
        ProductQuantity: 5,
        ProductStatus:   true,
        Car: shop.Car{
            Model:   "Corolla",
            Brand:   "Toyota",
            Year:    2018,
            Color:   "Blue",
            IsUsed:  false,
            Mileage: 0,
        },
    }
Enter fullscreen mode Exit fullscreen mode

We can now continue to use the methods we created in the shop package in the main function.

        //Add the products to the shop (shop1)
    shop1.AddProducts(item1, item2)

        //List all sold products ==> null
    shop1.ListSoldProducts()

    fmt.Printf("Total unsold products price: %v", shop1.TotalUnsoldProductsPrice())
    fmt.Println()

    shop1.ListProducts()

    shop1.SellProduct(1, 2)

    shop1.ListSoldProducts()

    shop1.ListProducts()

    fmt.Println(shop1.TotalSales())
Enter fullscreen mode Exit fullscreen mode

After this, we can save our work and run the go file using the go run filename command.

In our case, we are running the main file, so it'd be
go run main.go
and we'd see the details on the console.

Conclusion:

In summary, this lesson simulates a car shop where you can add products (cars), list all the sold and unsold products, sell products and check for the total sales.

Top comments (0)