Add saving of item prices for price tier. #780

This commit is contained in:
Korina Cordero 2024-01-16 16:28:26 +08:00
parent 022336ad8f
commit 6d7c8c5b53
8 changed files with 56 additions and 255 deletions

View file

@ -667,14 +667,6 @@ catalyst_auth:
acls: acls:
- id: item.menu - id: item.menu
label: Menu label: Menu
- id: item.list
label: List
- id: item.add
label: Add
- id: item.update
label: Update
- id: item.delete
label: Delete
- id: item_pricing - id: item_pricing
label: Item Pricing label: Item Pricing
acls: acls:

View file

@ -306,7 +306,3 @@ catalyst_menu:
acl: item_pricing.update acl: item_pricing.update
label: Item Pricing label: Item Pricing
parent: item parent: item
- id: item_list
acl: item.list
label: Items
parent: item

View file

@ -1,34 +0,0 @@
item_list:
path: /items
controller: App\Controller\ItemController::index
methods: [GET]
item_rows:
path: /items/rowdata
controller: App\Controller\ItemController::datatableRows
methods: [POST]
item_add_form:
path: /items/newform
controller: App\Controller\ItemController::addForm
methods: [GET]
item_add_submit:
path: /items
controller: App\Controller\ItemController::addSubmit
methods: [POST]
item_update_form:
path: /items/{id}
controller: App\Controller\ItemController::updateForm
methods: [GET]
item_update_submit:
path: /items/{id}
controller: App\Controller\ItemController::updateSubmit
methods: [POST]
item_delete:
path: /items/{id}
controller: App\Controller\ItemController::deleteSubmit
methods: [DELETE]

View file

@ -1,188 +0,0 @@
<?php
namespace App\Controller;
use Doctrine\ORM\Query;
use Doctrine\ORM\QueryBuilder;
use Doctrine\ORM\EntityManagerInterface;
use Doctrine\ORM\Query\Expr\Join;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Validator\Validator\ValidatorInterface;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\ParamConverter;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\IsGranted;
use App\Entity\ItemType;
use App\Entity\Item;
use App\Entity\Battery;
use App\Entity\ServiceOffering;
use Catalyst\MenuBundle\Annotation\Menu;
class ItemController extends Controller
{
/**
* @Menu(selected="item_list")
* @IsGranted("item.list")
*/
public function index ()
{
return $this->render('item/list.html.twig');
}
/**
* @IsGranted("item.list")
*/
public function datatableRows(Request $req)
{
// get query builder
$total_qb = $this->getDoctrine()
->getRepository(Item::class)
->createQueryBuilder('q');
// get datatable params
$datatable = $req->request->get('datatable');
// count total records
$tquery = $total_qb->select('COUNT(q)')
->leftJoin(Battery::class, 'battery', Join::WITH, 'battery.id = q.item_id')
->leftJoin(ServiceOffering::class, 'so', Join::WITH, 'so.id = q.item_id');
$this->setQueryFilters($datatable, $tquery);
$total = $tquery->getQuery()
->getSingleScalarResult();
// get current page number
$page = $datatable['pagination']['page'] ?? 1;
$perpage = $datatable['pagination']['perpage'];
$offset = ($page - 1) * $perpage;
// add metadata
$meta = [
'page' => $page,
'perpage' => $perpage,
'pages' => ceil($total / $perpage),
'total' => $total,
'sort' => 'asc',
'field' => 'id'
];
// reset query builder
$qb = $this->getDoctrine()
->getRepository(Item::class)
->createQueryBuilder('q');
// build query
$query = $qb->select('q')
->leftJoin(Battery::class, 'battery', Join::WITH, 'battery.id = q.item_id')
->leftJoin(ServiceOffering::class, 'so', Join::WITH, 'so.id = q.item_id');
$this->setQueryFilters($datatable, $query);
// check if sorting is present, otherwise use default
if (isset($datatable['sort']['field']) && !empty($datatable['sort']['field'])) {
$order = $datatable['sort']['sort'] ?? 'asc';
$query->orderBy('q.' . $datatable['sort']['field'], $order);
} else {
$query->orderBy('q.id', 'asc');
}
// get rows for this page
$obj_rows = $query->setFirstResult($offset)
->setMaxResults($perpage)
->getQuery()
->getResult();
// process rows
$rows = [];
foreach ($obj_rows as $orow) {
// add row data
$row['id'] = $orow->getID();
// add row metadata
$row['meta'] = [
'update_url' => '',
'delete_url' => ''
];
// add crud urls
if ($this->isGranted('item_price.update'))
$row['meta']['update_url'] = $this->generateUrl('item_price_update_form', ['id' => $row['id']]);
if ($this->isGranted('item_price.delete'))
$row['meta']['delete_url'] = $this->generateUrl('item_price_delete', ['id' => $row['id']]);
$rows[] = $row;
}
// response
return $this->json([
'meta' => $meta,
'data' => $rows
]);
}
/**
* @Menu(selected="item.list")
* @IsGranted("item.add")
*/
public function addForm(EntityManagerInterface $em)
{
$item = new Item();
// get the sets for the dropdowns
$sets = $this->generateFormSets($em);
$params = [
'obj' => $item,
'sets' => $sets,
'mode' => 'create',
];
// response
return $this->render('item/form.html.twig', $params);
}
protected function generateFormSets(EntityManagerInterface $em)
{
// item types
$item_types = $em->getRepository(ItemType::class)->findby([], ['name' => 'asc']);
$item_type_set = [];
foreach ($item_types as $it)
{
$item_type_set[$it->getID()] = $it->getName();
}
// batteries
$batts = $em->getRepository(Battery::class)->findAll();
$batt_set = [];
foreach ($batts as $batt)
{
$batt_set[$batt->getID()] = $batt->getModel()->getName() . ' ' . $batt->getSize()->getName();
}
// service offerings
$services = $em->getRepository(ServiceOffering::class)->findBy([],['name' => 'asc']);
$service_set = [];
foreach ($services as $service)
{
$service_set[$service->getID()] = $service->getName();
}
return [
'item_types' => $item_type_set,
'batteries' => $batt_set,
'services' => $service_set,
];
}
protected function setQueryFilters($datatable, QueryBuilder $query)
{
// TODO: add filter for item type.
// TODO: fix filter for name since name is with the associated entity
if (isset($datatable['query']['data-rows-search']) && !empty($datatable['query']['data-rows-search'])) {
$query->where('q.name LIKE :filter')
->setParameter('filter', '%' . $datatable['query']['data-rows-search'] . '%');
}
}
}

View file

@ -63,25 +63,26 @@ class ItemPricingController extends Controller
// get the item type // get the item type
$item_type = $em->getRepository(ItemType::class)->find($it_id); $item_type = $em->getRepository(ItemType::class)->find($it_id);
if ($item_type->getCode() == 'battery')
{
// get batteries
$items = $em->getRepository(Battery::class)->findBy(['flag_active' => true], ['id' => 'asc']);
}
else
{
// get service offerings
$items = $em->getRepository(ServiceOffering::class)->findBy([], ['id' => 'asc']);
}
// on default price tier
if ($pt_id == 0) if ($pt_id == 0)
{ {
// default price tier, update battery or service offering, depending on item type // default price tier, update battery or service offering, depending on item type
// NOTE: battery and service offering prices or fees are stored as decimal. // NOTE: battery and service offering prices or fees are stored as decimal.
if ($item_type->getCode() == 'battery')
{
// get batteries
$items = $em->getRepository(Battery::class)->findBy(['flag_active' => true], ['id' => 'asc']);
}
else
{
// get service offerings
$items = $em->getRepository(ServiceOffering::class)->findBy([], ['id' => 'asc']);
}
foreach ($items as $item) foreach ($items as $item)
{ {
$item_id = $item->getID(); $item_id = $item->getID();
if (isset[$prices[$item_id]]) if (isset($prices[$item_id]))
{ {
// check item type // check item type
if ($item_type->getCode() == 'battery') if ($item_type->getCode() == 'battery')
@ -96,8 +97,42 @@ class ItemPricingController extends Controller
// get the price tier // get the price tier
$price_tier = $em->getRepository(PriceTier::class)->find($pt_id); $price_tier = $em->getRepository(PriceTier::class)->find($pt_id);
// TODO: finish this $item_prices = $price_tier->getItems();
// clear the tier's item prices
foreach ($item_prices as $ip)
{
$em->remove($ip);
}
// update the tier's item prices
foreach ($items as $item)
{
$item_id = $item->getID();
$item_price = new ItemPrice();
$item_price->setItemType($item_type)
->setPriceTier($price_tier)
->setItemID($item_id);
if (isset($prices[$item_id]))
{
$item_price->setPrice($price[$item_id] * 100);
}
else
{
$item_price->setPrice($item->getPrice() * 100);
}
// save
$em->persist($item_price);
}
} }
$em->flush();
return $this->redirectToRoute('item_pricing');
} }
/** /**
@ -117,7 +152,7 @@ class ItemPricingController extends Controller
$pt = $em->getRepository(PriceTier::class)->find($pt_id); $pt = $em->getRepository(PriceTier::class)->find($pt_id);
// get the items under the price tier // get the items under the price tier
$pt_items = $pt->getItems(); $pt_items = $pt->getItemPrices();
foreach ($pt_items as $pt_item) foreach ($pt_items as $pt_item)
{ {
// make item price hash // make item price hash

View file

@ -9,7 +9,7 @@ use Doctrine\ORM\Mapping as ORM;
* @ORM\Table(name="item") * @ORM\Table(name="item")
*/ */
class Item class ItemPrice
{ {
// unique id // unique id
/** /**
@ -20,7 +20,7 @@ class Item
protected $id; protected $id;
/** /**
* @ORM\ManyToOne(targetEntity="PriceTier", inversedBy="items") * @ORM\ManyToOne(targetEntity="PriceTier", inversedBy="item_prices")
* @ORM\JoinColumn(name="price_tier_id", referencedColumnName="id") * @ORM\JoinColumn(name="price_tier_id", referencedColumnName="id")
*/ */
protected $price_tier; protected $price_tier;

View file

@ -37,7 +37,7 @@ class ItemType
// items under an item type // items under an item type
/** /**
* @ORM\OneToMany(targetEntity="Item", mappedBy="item_type") * @ORM\OneToMany(targetEntity="ItemPrice", mappedBy="item_type")
*/ */
protected $items; protected $items;

View file

@ -34,9 +34,9 @@ class PriceTier
// items under a price tier // items under a price tier
/** /**
* @ORM\OneToMany(targetEntity="Item", mappedBy="price_tier") * @ORM\OneToMany(targetEntity="ItemPrice", mappedBy="price_tier")
*/ */
protected $items; protected $item_prices;
public function __construct() public function __construct()
{ {
@ -80,9 +80,9 @@ class PriceTier
return $this; return $this;
} }
public function getItems() public function getItemPrices()
{ {
return $this->items; return $this->item_prices;
} }
} }