package controllers import ( "errors" "strconv" "nearle/models" "nearle/repositories" "github.com/gofiber/fiber/v2" ) /* Attaching sizes to a product, and taking them off again. The pair that was missing. `createproductvariant` wrote a name into a table without a parent, so there was no way to say "500ml is a size of Coke" — and without that the ordering screen had nothing but `products.variants` to work from, a bare group number that is 0 on every product. */ // AddProductVariant — POST /products/addproductvariant // // Body: {tenantid, productid, variantproductid, variantname, varianttype?, price?} func (ctl *ProductController) AddProductVariant(c *fiber.Ctx) error { var body models.Productvariant if err := c.BodyParser(&body); err != nil { return c.Status(fiber.StatusBadRequest).JSON(fiber.Map{ "code": fiber.StatusBadRequest, "status": false, "message": "could not read the request body", }) } if body.Tenantid <= 0 { return c.Status(fiber.StatusBadRequest).JSON(fiber.Map{ "code": fiber.StatusBadRequest, "status": false, "message": "tenantid is required", }) } saved, err := ctl.productService.AddProductVariant(body) if err != nil { // The refusals are all about the CALLER's request, so they answer 400 // with the reason. Anything else is ours and answers 500. for _, known := range []error{ repositories.ErrVariantParentMissing, repositories.ErrVariantProductMissing, repositories.ErrVariantSelfReference, repositories.ErrVariantNotYours, repositories.ErrVariantDuplicate, } { if errors.Is(err, known) { return c.Status(fiber.StatusBadRequest).JSON(fiber.Map{ "code": fiber.StatusBadRequest, "status": false, "message": err.Error(), }) } } return c.Status(fiber.StatusInternalServerError).JSON(fiber.Map{ "code": fiber.StatusInternalServerError, "status": false, "message": "could not add the variant", }) } return c.Status(fiber.StatusCreated).JSON(fiber.Map{ "code": fiber.StatusCreated, "status": true, "message": "Success", "details": saved, }) } // RemoveProductVariant — DELETE /products/removeproductvariant?tenantid=&variantid= // // Detaches the size. Neither product is deleted: a variant is a relationship, // and removing it leaves two ordinary products behind. func (ctl *ProductController) RemoveProductVariant(c *fiber.Ctx) error { tenantid, _ := strconv.Atoi(c.Query("tenantid")) variantid, _ := strconv.Atoi(c.Query("variantid")) if tenantid <= 0 || variantid <= 0 { return c.Status(fiber.StatusBadRequest).JSON(fiber.Map{ "code": fiber.StatusBadRequest, "status": false, "message": "tenantid and variantid are both required", }) } if err := ctl.productService.RemoveProductVariant(tenantid, variantid); err != nil { return c.Status(fiber.StatusInternalServerError).JSON(fiber.Map{ "code": fiber.StatusInternalServerError, "status": false, "message": "could not remove the variant", }) } return c.JSON(fiber.Map{ "code": fiber.StatusOK, "status": true, "message": "Success", }) }