protected function setUp() { $locSrv = new LocationsService(); $location = new Location("Location"); $location->id = $locSrv->create($location); $cashRegSrv = new CashRegistersService(); $cashReg = new CashRegister("CashReg", $location->id, 1); $cashRegId = $cashRegSrv->create($cashReg); // Create a cash session $srv = new CashesService(); $cash = $srv->add($cashRegId); $this->cashId = $cash->id; $srv = new CurrenciesService(); $eur = new Currency("Eur", "€", ",", ".", "#,##0.00\$", 1, true, false); $this->currencyId = $srv->create($eur); }
static function delete($id) { $pdo = PDOBuilder::getPDO(); $db = DB::get(); $ticket = TicketsService::get($id); if ($ticket === null) { return false; } $cashSrv = new CashesService(); $cash = $cashSrv->get($ticket->cashId); if ($cash === null || $cash->isClosed()) { return false; } $cashRegSrv = new CashRegistersService(); $cashReg = $cashRegSrv->getFromCashId($cash->id); // As cash must be opened, cashregister location is considered accurate $locationId = $cashReg->locationId; $newTransaction = !$pdo->inTransaction(); if ($newTransaction) { $pdo->beginTransaction(); } // Delete ticket lines // Also check for prepayments refill $stmtLines = $pdo->prepare("DELETE FROM TICKETLINES " . "WHERE TICKET = :id"); $stmtLines->bindParam(":id", $ticket->id); foreach ($ticket->lines as $line) { // Update stock if ($line->productId !== null) { $discountRate = $ticket->discountRate; $fullDiscount = $discountRate + $line->discountRate; $discountPrice = $line->price * (1.0 - $fullDiscount); $move = new StockMove($ticket->date, StockMove::REASON_IN_REFUND, $line->productId, $locationId, $line->attrSetInstId, $line->quantity, $discountPrice); if (StocksService::addMove($move) === false) { if ($newTransaction) { $pdo->rollback(); } return false; } } // Check prepayment refill // Refill is not affected by discount $prepaidIds = ProductsService::getPrepaidIds(); if ($ticket->customerId !== null && in_array($line->productId, $prepaidIds)) { $custSrv = new CustomersService(); $ok = $custSrv->addPrepaid($ticket->customerId, -$line->price * $line->quantity); if ($ok === false) { if ($newTransaction) { $pdo->rollback(); } return false; } } } if ($stmtLines->execute() === false) { if ($newTransaction) { $pdo->rollback(); } return false; } // Delete payments // Also check for prepayment debit and debt $stmtPay = $pdo->prepare("DELETE FROM PAYMENTS WHERE RECEIPT = :id"); $stmtPay->bindParam(":id", $ticket->id); foreach ($ticket->payments as $payment) { if ($payment->type == 'prepaid' || $payment->type == 'debt') { $custSrv = new CustomersService(); if ($payment->type == 'prepaid') { $ok = $custSrv->addPrepaid($ticket->customerId, $payment->amount); } else { $ok = $custSrv->recoverDebt($ticket->customerId, $payment->amount); } if ($ok === false) { if ($newTransaction) { $pdo->rollback(); } return false; } } } if ($stmtPay->execute() === false) { if ($newTransaction) { $pdo->rollback(); } return false; } // Delete taxlines $stmtTax = $pdo->prepare("DELETE FROM TAXLINES WHERE RECEIPT = :id"); $stmtTax->bindParam(":id", $ticket->id); if ($stmtTax->execute() === false) { if ($newTransaction) { $pdo->rollback(); } return false; } // Delete ticket $discountRate = $ticket->discountRate; $stmtTkt = $pdo->prepare("DELETE FROM TICKETS WHERE ID = :id"); $stmtTkt->bindParam(':id', $ticket->id); if ($stmtTkt->execute() === false) { if ($newTransaction) { $pdo->rollback(); } return false; } // Delete receipt $stmtRcpt = $pdo->prepare("DELETE FROM RECEIPTS WHERE ID = :id"); $stmtRcpt->bindParam(":id", $ticket->id); if ($stmtRcpt->execute() === false) { if ($newTransaction) { $pdo->rollback(); } return false; } if ($newTransaction) { $pdo->commit(); } return true; }
protected function setUp() { // Attribute set $set = new AttributeSet("set"); $attr = new Attribute("attr", 1); $val = new AttributeValue("value"); $attr->id = AttributesService::createAttribute($attr); $val->id = AttributesService::createValue($val, $attr->id); $attr->addValue($val); $set->addAttribute($attr); $set->id = AttributesService::createSet($set); // Product, tax and category $taxCat = new TaxCat("Tax"); $tax = new Tax(null, "Tax", stdtimefstr("2001-01-01 00:00:00"), 0.1); $taxCat->addTax($tax); $taxCat->id = TaxesService::createCat($taxCat); $taxCat2 = new TaxCat("Tax2"); $tax2 = new Tax(null, "Tax2", stdtimefstr("2001-01-01 00:00:00"), 0.2); $taxCat2->addTax($tax2); $taxCat2->id = TaxesService::createCat($taxCat2); $pdo = PDOBuilder::getPDO(); $stmt = $pdo->prepare("INSERT INTO CATEGORIES (ID, NAME) " . "VALUES (:id, :name)"); $stmt->execute(array(":id" => "-1", ":name" => "Refill")); $cat = new Category(null, "Category", false, 1); $cat->id = CategoriesService::createCat($cat); $prd = new Product("REF", "product", 1.0, $cat->id, null, 1, $taxCat->id, true, false, 0.5, $set->id); $prd->id = ProductsService::create($prd); $prd2 = new Product("REF2", "product2", 2.0, $cat->id, null, 1, $taxCat2->id, true, false, 0.5, null); $prd2->id = ProductsService::create($prd2); $prdRefill = new Product("REFILL", "Refill", 1.0, "-1", null, 1, $taxCat->id, true, false); $prdRefill->id = ProductsService::create($prdRefill); // Tariff area $srvArea = new TariffAreasService(); $area = new TariffArea("area", 1); $area->addPrice($prd->id, 0.8); $area->id = $srvArea->create($area); $this->areaId = $area->id; // Customer $srvCust = new CustomersService(); $cust = new Customer(1, "Cust", "It's me", "card", null, null, 50.0, 10.0, 5.0, stdtimefstr("2012-01-01 00:00:00"), "It's", "me", "*****@*****.**", "012345", "23456", "11111", "Address1", "Address2", "59000", "City", "Region", "France", "Note", true); $cust->id = $srvCust->create($cust); $this->custId = $cust->id; // Location $locSrv = new LocationsService(); $loc = new Location("Location"); $loc->id = $locSrv->create($loc); $this->locationId = $loc->id; // Cash register $srvCashReg = new CashRegistersService(); $cashReg = new CashRegister("Cash", $loc->id, 1); $cashReg->id = $srvCashReg->create($cashReg); // Cash $srvCash = new CashesService(); $cash = $srvCash->add($cashReg->id); $cash->openDate = stdtimefstr("2000-02-02 02:02:02"); $srvCash->update($cash); $this->cashId = $cash->id; // User $srvUsers = new UsersService(); $user = new User("User", null, null, "0", true, false); $user->id = $srvUsers->create($user); // Currency $curr = new Currency("Eur", "€", ",", ".", "#,##0.00\$", 1, true, false); $srvCurr = new CurrenciesService(); $curr->id = $srvCurr->create($curr); // Discount profile $profSrv = new DiscountProfilesService(); $prof = new DiscountProfile("Profile", 0.1); $prof->id = $profSrv->create($prof); $this->discountProfilId = $prof->id; // Ticket $tkt1 = array("date" => stdtimefstr("2012-01-01 00:00:00"), "userId" => $user->id, "customerId" => null, "type" => Ticket::TYPE_SELL, "custCount" => 3, "tariffAreaId" => null, "discountRate" => 0.0, "discountProfileId" => null, "payments" => array(array("type" => "cash", "amount" => 10, "currencyId" => $curr->id, "currencyAmount" => 12)), "lines" => array(array("dispOrder" => 1, "productId" => $prd->id, "taxId" => $tax->id, "attributes" => null, "quantity" => 1.0, "price" => 10.0, "discountRate" => 0.0))); $jsAttr = array("attributeSetId" => $set->id, "values" => array(array("id" => $attr->id, "value" => "value"))); $tkt2 = array("date" => stdtimefstr("2012-01-01 00:00:00"), "userId" => $user->id, "customerId" => null, "type" => Ticket::TYPE_SELL, "custCount" => 3, "tariffAreaId" => null, "discountRate" => 0.25, "discountProfileId" => $prof->id, "payments" => array(array("type" => "cash", "amount" => 10, "currencyId" => $curr->id, "currencyAmount" => 12)), "lines" => array(array("dispOrder" => 1, "productId" => $prd->id, "taxId" => $tax->id, "attributes" => $jsAttr, "quantity" => 1.0, "price" => 10.0, "discountRate" => 0.25))); $this->jsTicket1 = json_encode($tkt1); $this->jsTicket2 = json_encode($tkt2); }
/** Run the service and set result. */ protected function proceed() { $srv = new CashesService(); $db = DB::get(); switch ($this->action) { case 'get': if (isset($this->params['id'])) { $ret = $srv->get($this->params['id']); } else { $ret = $srv->getCashRegister($this->params['cashRegisterId']); if ($ret === null || $ret->isClosed()) { $ret = null; } } $this->succeed($ret); break; case 'zticket': $ret = $srv->getZTicket($this->params['id']); $this->succeed($ret); break; case 'search': $cashRegisterId = $this->getParam("cashRegisterId"); $dateStart = $this->getParam("dateStart"); $dateStop = $this->getParam("dateStop"); $conditions = array(); if ($cashRegisterId !== null) { $conditions[] = array("cashRegisterId", "=", $cashRegisterId); } if ($dateStart !== null) { $conditions[] = array("openDate", ">=", $db->dateVal($dateStart)); } if ($dateStop !== null) { $conditions[] = array("closeDate", "<=", $db->dateVal($dateStop)); } $this->succeed($srv->search($conditions)); break; case 'update': $json = json_decode($this->params['cash']); $open = null; $id = null; if (property_exists($json, 'id')) { $id = $json->id; } if (property_exists($json, 'openDate')) { $open = $json->openDate; } $close = null; if (property_exists($json, 'closeDate')) { $close = $json->closeDate; } $openCash = null; if (property_exists($json, 'openCash')) { $openCash = $json->openCash; } $closeCash = null; if (property_exists($json, 'closeCash')) { $closeCash = $json->closeCash; } $expectedCash = null; if (property_exists($json, 'expectedCash')) { $expectedCash = $json->expectedCash; } $cashRegisterId = $json->cashRegisterId; $sequence = null; if (property_exists($json, 'sequence')) { $sequence = $json->sequence; } if ($id !== null) { // Update an existing cash $cash = Cash::__build($id, $cashRegisterId, $sequence, $open, $close, $openCash, $closeCash, $expectedCash); if ($srv->update($cash)) { $this->succeed($cash); } else { $this->fail(APIError::$ERR_GENERIC); } } else { // Create a cash and update with given data if ($srv->add($cashRegisterId)) { $cash = $srv->getCashRegister($cashRegisterId); $cash->openDate = $open; $cash->closeDate = $close; $cash->openCash = $openCash; $cash->closeCash = $closeCash; $cash->expectedCash = $expectedCash; if ($srv->update($cash)) { $this->succeed($cash); } else { $this->fail(APIError::$ERR_GENERIC); } } else { $this->fail(APIError::$ERR_GENERIC); } } break; } }
protected function proceed() { switch ($this->action) { case 'getShared': $tkt = TicketsService::getSharedTicket($this->params['id']); $this->succeed($tkt); break; case 'getAllShared': $tkts = TicketsService::getAllSharedTickets(); $this->succeed($tkts); break; case 'delShared': $this->succeed(TicketsService::deleteSharedTicket($this->params['id'])); break; case 'share': $json = json_decode($this->params['ticket']); $ticket = SharedTicket::__build($json->id, $json->label, $json->customerId, $json->custCount, $json->tariffAreaId, $json->discountProfileId, $json->discountRate); $lines = array(); foreach ($json->lines as $jsLine) { // Get line info $tktLine = new SharedTicketLines($ticket->id, $jsLine->dispOrder, $jsLine->productId, $jsLine->taxId, $jsLine->quantity, $jsLine->discountRate, $jsLine->price, $jsLine->attributes); $lines[] = $tktLine; } if (TicketsService::createSharedTicket($ticket, $lines) === false) { $this->succeed(TicketsService::updateSharedTicket($ticket, $lines)); } else { $this->succeed(true); } break; case 'getOpen': $this->succeed(TicketsService::getOpen()); break; case 'search': $this->succeed(TicketsService::search($this->getParam("ticketId"), $this->getParam("ticketType"), $this->getParam("cashId"), $this->getParam("dateStart"), $this->getParam("dateStop"), $this->getParam("customerId"), $this->getParam("userId"), $this->getParam("limit"))); break; case 'delete': if (!TicketsService::delete($this->getParam("id"))) { $this->fail(APIError::$ERR_GENERIC); } else { $this->succeed(true); } break; case 'save': // Receive ticket data as json // Convert single ticket to array for consistency if (isset($this->params['tickets'])) { $json = json_decode($this->params['tickets']); } else { $json = array(json_decode($this->params['ticket'])); } // Get location from cash register $cashId = $this->params['cashId']; $cashSrv = new CashesService(); $cash = $cashSrv->get($cashId); if ($cash === null) { $this->fail(new APIError("Unknown cash session")); break; } $cashRegSrv = new CashRegistersService(); $cashReg = $cashRegSrv->get($cash->cashRegisterId); if ($cashReg === null) { $this->fail(new APIError("Cash register not found")); break; } $locationId = $cashReg->locationId; if ($locationId === null) { $this->fail(new APIError("Location not set")); break; } // Register tickets $ticketsCount = count($json); $successes = 0; $pdo = PDOBuilder::getPDO(); if (!$pdo->beginTransaction()) { $this->fail(APIError::$ERR_GENERIC); break; } foreach ($json as $jsonTkt) { if ($jsonTkt === null) { $this->fail(new APIError("Unable to decode ticket")); break; } $ticketId = $jsonTkt->ticketId; $userId = $jsonTkt->userId; $customerId = $jsonTkt->customerId; $date = $jsonTkt->date; $tktType = $jsonTkt->type; $custCount = $jsonTkt->custCount; $tariffAreaId = $jsonTkt->tariffAreaId; $discountRate = $jsonTkt->discountRate; $discountProfileId = $jsonTkt->discountProfileId; // Get lines $lines = array(); foreach ($jsonTkt->lines as $jsLine) { // Get line info $number = $jsLine->dispOrder; if (property_exists($jsLine, "productId")) { $productId = $jsLine->productId; } else { $productId = null; } $productLabel = $jsLine->productLabel; $quantity = $jsLine->quantity; $price = $jsLine->price; $taxId = $jsLine->taxId; $lineDiscountRate = $jsLine->discountRate; if ($jsLine->attributes !== null) { $jsAttr = $jsLine->attributes; $attrSetId = $jsAttr->attributeSetId; $values = $jsAttr->values; $desc = ""; foreach ($values as $val) { $desc .= $val->value . ", "; } $desc = substr($desc, 0, -2); $attrs = new AttributeSetInstance($attrSetId, $desc); foreach ($values as $val) { $attrVal = new AttributeInstance(null, $val->id, $val->value); $attrs->addAttrInst($attrVal); } $attrsId = TicketsService::createAttrSetInst($attrs); if ($attrsId === false) { $this->fail(new APIError("Unknown attributes")); break; } } else { $attrsId = null; } $product = ProductsService::get($productId); if ($product === null) { $product = new Product($productId, $productId, $productId, null, null, null, $taxId, true, false); } $tax = TaxesService::getTax($taxId); if ($tax == null) { $this->fail(new APIError("Unknown tax")); break; } $newLine = new TicketLine($number, $product, $attrsId, $quantity, $price, $tax, $lineDiscountRate, $productLabel); $lines[] = $newLine; } if (count($lines) != count($jsonTkt->lines)) { break; } // Get payments $payments = array(); foreach ($jsonTkt->payments as $jspay) { $type = $jspay->type; $amount = $jspay->amount; if (!property_exists($jspay, "currencyId") || $jspay->currencyId === null) { $currSrv = new CurrenciesService(); $currencyId = $currSrv->getDefault()->id; $currencyAmount = $amount; } else { $currencyId = $jspay->currencyId; $currencyAmount = $jspay->currencyAmount; } $backType = null; $backAmount = null; if (property_exists($jspay, "back") && $jspay->back !== null) { $backType = $jspay->back->type; $backAmount = $jspay->back->amount; } $payment = new Payment($type, $amount, $currencyId, $currencyAmount, $backType, $backAmount); $payments[] = $payment; } $ticket = new Ticket($tktType, $userId, $date, $lines, $payments, $cashId, $customerId, $custCount, $tariffAreaId, $discountRate, $discountProfileId); $ticket->ticketId = $ticketId; if (isset($jsonTkt->id)) { // Ticket edit $ticket->id = $jsonTkt->id; //Check if cash is still opened $oldTicket = TicketsService::get($id); if ($oldTicket != null) { $cashSrv = new CashesService(); $cash = $cashSrv->get($oldTicket->cashId); if ($cash->isClosed()) { $this->fail(new APIError("Cannot edit a ticket from " . "a closed cash")); break; } // Delete the old ticket and recreate if (TicketsService::delete($oldTicket->id) && TicketsService::save($ticket, $locationId)) { $successes++; } else { $this->fail(new APIError("Unable to edit ticket")); break; } } } else { // New ticket if (TicketsService::save($ticket)) { $successes++; } else { $this->fail(new APIError("Unable to save ticket")); break; } } } // Check if all tickets were saved, if not rollback and error $ret = $successes == $ticketsCount; if ($ret === true) { if ($pdo->commit()) { $ticketId++; $cashRegSrv->setNextTicketId($ticketId, $cash->cashRegisterId); $this->succeed(array("saved" => $ticketsCount)); } else { $this->fail(APIError::$ERR_GENERIC); } } else { $pdo->rollback(); if ($this->result === null) { $this->fail(APIError::$ERR_GENERIC); } } break; } }
/** @depends testGet */ public function testDeleteClosed() { $date = stdtimefstr("2013-01-01 00:00:00"); $ticket = new Ticket(Ticket::TYPE_SELL, $this->user->id, $date, array(), array(), $this->cash->id); $id = TicketsService::save($ticket, $this->location->id); $this->cash->closeDate = stdtimefstr("2013-01-01 12:00:00"); $cashSrv = new CashesService(); $cashSrv->update($this->cash); $this->assertFalse(TicketsService::delete($id), "Closed ticket should not be deleted"); $this->assertNotNull(TicketsService::get($id), "Ticket is not there anymore"); }
/** Create a new cash for the given host and return it. * Returns null in case of error. */ public function add($cashRegisterId) { $pdo = PDOBuilder::getPDO(); $id = md5(time() . rand()); $stmt = $pdo->prepare("INSERT INTO CLOSEDCASH (MONEY, CASHREGISTER_ID, " . "HOSTSEQUENCE) VALUES (:id, :crId, :sequence)"); $sequence = CashesService::getLastSequence($cashRegisterId, $pdo) + 1; $stmt->bindParam(':id', $id); $stmt->bindParam(':crId', $cashRegisterId); $stmt->bindParam(':sequence', $sequence); if ($stmt->execute() !== false) { return $this->get($id); } else { return null; } }
public function testUpdate() { $broker = new APIBroker("CashesAPI"); $srv = new CashesService(); $cash = $srv->add($this->cashRegisterId); $cash->openDate = stdtimefstr("2002-02-02 02:02:02"); $cash->closeDate = stdtimefstr("2002-02-03 03:03:03"); $cash->openCash = 1.0; $cash->closeCash = 13.0; $cash->expectedCash = 15.0; $result = $broker->run("update", array("cash" => json_encode($cash))); $this->assertEquals(APIResult::STATUS_CALL_OK, $result->status, "Result status check failed"); $content = $result->content; $this->assertNotNull($content, "Content is null"); $this->assertEquals($cash->id, $content->id, "Id mismatch"); $this->assertEquals($cash->cashRegisterId, $content->cashRegisterId, "Cash register id mismatch"); $this->assertEquals($cash->sequence, $content->sequence, "Sequence mismatch"); $this->assertEquals($cash->openDate, $content->openDate, "Open date mismatch"); $this->assertEquals($cash->closeDate, $content->closeDate, "Close date mismatch"); $this->assertEquals($cash->openCash, $content->openCash, "Open cash mismatch"); $this->assertEquals($cash->closeCash, $content->closeCash, "Close cash mismatch"); $this->assertEquals($cash->expectedCash, $content->expectedCash, "Expected cash mismatch"); }
public function testGetInexistent() { $srv = new CashesService(); $cashReg = $srv->get("none"); $this->assertNull($cashReg, "Inexistent cash register found"); }
/** @depends testAdd * @depends testGet */ public function testUpdate() { $srv = new CashesService(); $cash = $srv->add($this->cashRegisterId); // Edit open date $cash->openDate = stdtimefstr("2000-02-02 02:02:02"); $cash->openCash = 10.0; $srv->update($cash); $read = $srv->get($cash->id); $this->assertNotNull($read, "Created cash not found"); $this->assertEquals($cash->id, $read->id, "Id was modified"); $this->assertEquals($cash->cashRegisterId, $read->cashRegisterId, "Cash register id was modified"); $this->assertEquals($cash->sequence, $read->sequence, "Sequence was modified"); $this->assertEquals($cash->openDate, $read->openDate, "Open date Mismatch"); $this->assertEquals($cash->closeDate, $read->closeDate, "Close date was modified"); $this->assertEquals($cash->openCash, $read->openCash, "Open cash mismatch"); $this->assertEquals($cash->closeCash, $read->closeCash, "Close cash was modified"); $this->assertEquals($cash->expectedCash, $read->expectedCash, "Expected cash was modified"); // Edit close date $cash->closeDate = stdtimefstr("2000-02-03 02:02:02"); $cash->closeCash = 12.0; $cash->expectedCash = 25.0; $srv->update($cash); $read = $srv->get($cash->id); $this->assertNotNull($read, "Created cash not found"); $this->assertEquals($cash->id, $read->id, "Id was modified"); $this->assertEquals($cash->cashRegisterId, $read->cashRegisterId, "Cash register id was modified"); $this->assertEquals($cash->sequence, $read->sequence, "Sequence was modified"); $this->assertEquals($cash->openDate, $read->openDate, "Open date was modified"); $this->assertEquals($cash->closeDate, $read->closeDate, "Close date was modified"); $this->assertEquals($cash->openCash, $read->openCash, "Open cash was modified"); $this->assertEquals($cash->closeCash, $read->closeCash, "Close cash mismatch"); $this->assertEquals($cash->expectedCash, $read->expectedCash, "Expected cash was modified"); // Edit open and close date $cash->openDate = stdtimefstr("2001-02-02 03:03:03"); $cash->closeDate = stdtimefstr("2001-02-03 03:03:03"); $cash->openCash = 9.0; $cash->closeCash = 9.1; $cash->expectedCash = 9.199999999999999; $srv->update($cash); $read = $srv->get($cash->id); $this->assertNotNull($read, "Created cash not found"); $this->assertEquals($cash->id, $read->id, "Id was modified"); $this->assertEquals($cash->cashRegisterId, $read->cashRegisterId, "Cash register id was modified"); $this->assertEquals($cash->sequence, $read->sequence, "Sequence was modified"); $this->assertEquals($cash->openDate, $read->openDate, "Open date mismatch"); $this->assertEquals($cash->closeDate, $read->closeDate, "Close date mismatch"); $this->assertEquals($cash->openCash, $read->openCash, "Open cash mismatch"); $this->assertEquals($cash->closeCash, $read->closeCash, "Close cash mismatch"); $this->assertEquals($cash->expectedCash, $read->expectedCash, "Expected cash was modified"); }