Ejemplo n.º 1
0
 static function save($ticket)
 {
     $pdo = PDOBuilder::getPDO();
     $db = DB::get();
     $cashRegSrv = new CashRegistersService();
     $cashReg = $cashRegSrv->getFromCashId($ticket->cashId);
     if ($cashReg === null) {
         return false;
     }
     $locationId = $cashReg->locationId;
     $newTransaction = !$pdo->inTransaction();
     if ($newTransaction) {
         $pdo->beginTransaction();
     }
     $id = md5(time() . rand());
     $stmtRcpt = $pdo->prepare("INSERT INTO RECEIPTS\t(ID, MONEY, DATENEW) " . "VALUES (:id, :money, :date)");
     $stmtRcpt->bindParam(":id", $id);
     $stmtRcpt->bindParam(":money", $ticket->cashId);
     $stmtRcpt->bindParam(":date", $db->dateVal($ticket->date));
     if ($stmtRcpt->execute() === false) {
         if ($newTransaction) {
             $pdo->rollback();
         }
         return false;
     }
     // Get next ticket number
     if ($ticket->ticketId === null) {
         $nextNum = $cashReg->nextTicketId;
         $cashRegSrv->incrementNextTicketId($cashReg->id);
         $ticket->ticketId = $nextNum;
     }
     //  Insert ticket
     $discountRate = $ticket->discountRate;
     $stmtTkt = $pdo->prepare("INSERT INTO TICKETS (ID, TICKETID, " . "TICKETTYPE, PERSON, CUSTOMER, CUSTCOUNT, TARIFFAREA, " . "DISCOUNTRATE, DISCOUNTPROFILE_ID) VALUES " . "(:id, :tktId, :tktType, :person, :cust, :custcount, :taId, " . ":discRate, :discProfId)");
     $stmtTkt->bindParam(':id', $id, \PDO::PARAM_STR);
     $stmtTkt->bindParam(':tktId', $ticket->ticketId, \PDO::PARAM_INT);
     $stmtTkt->bindParam(":tktType", $ticket->type);
     $stmtTkt->bindParam(':person', $ticket->userId);
     $stmtTkt->bindParam(':cust', $ticket->customerId);
     $stmtTkt->bindParam(":custcount", $ticket->custCount);
     $stmtTkt->bindParam(":taId", $ticket->tariffAreaId);
     $stmtTkt->bindParam(":discRate", $ticket->discountRate);
     $stmtTkt->bindParam(":discProfId", $ticket->discountProfileId);
     if ($stmtTkt->execute() === false) {
         if ($newTransaction) {
             $pdo->rollback();
         }
         return false;
     }
     // Insert ticket lines
     // Also check for prepayments refill
     $stmtLines = $pdo->prepare("INSERT INTO TICKETLINES (TICKET, LINE, " . "PRODUCT, ATTRIBUTESETINSTANCE_ID, UNITS, PRICE, TAXID, " . "DISCOUNTRATE, ATTRIBUTES) VALUES (:id, :line, :prdId, " . ":attrSetInstId, :qty, :price, :taxId, :discRate, :attrs)");
     foreach ($ticket->lines as $line) {
         $fullDiscount = $discountRate + $line->discountRate;
         $discountPrice = $line->price * (1.0 - $fullDiscount);
         $stmtLines->bindParam(":id", $id);
         $stmtLines->bindParam(":line", $line->dispOrder);
         $stmtLines->bindParam(":prdId", $line->productId);
         $stmtLines->bindParam(":attrSetInstId", $line->attrSetInstId);
         $stmtLines->bindParam(":qty", $line->quantity);
         $stmtLines->bindParam(":price", $line->price);
         $stmtLines->bindParam(":taxId", $line->taxId);
         $stmtLines->bindParam(":discRate", $line->discountRate);
         $stmtLines->bindParam(":attrs", $line->attributes);
         if ($stmtLines->execute() === false) {
             if ($newTransaction) {
                 $pdo->rollback();
             }
             return false;
         }
         // Update stock
         if ($line->productId !== null) {
             $move = new StockMove($ticket->date, StockMove::REASON_OUT_SELL, $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;
             }
         }
     }
     // Insert payments
     // Also check for prepayment debit and debt recovery
     $stmtPay = $pdo->prepare("INSERT INTO PAYMENTS (ID, RECEIPT, PAYMENT, " . "TOTAL, CURRENCY, TOTALCURRENCY, PAIRED_WITH) VALUES " . "(:id, :rcptId, :type, :amount, :currId, :currAmount, " . ":pair)");
     foreach ($ticket->payments as $payment) {
         $paymentId = md5(time() . rand());
         $stmtPay->bindParam(":id", $paymentId);
         $stmtPay->bindParam(":rcptId", $id);
         $stmtPay->bindParam(":type", $payment->type);
         $stmtPay->bindParam(":amount", $payment->amount);
         $stmtPay->bindParam(":currId", $payment->currencyId);
         $stmtPay->bindParam(":currAmount", $payment->currencyAmount);
         $stmtPay->bindValue(":pair", null);
         if ($stmtPay->execute() === false) {
             if ($newTransaction) {
                 $pdo->rollback();
             }
             return false;
         }
         // Insert back payment if any
         if ($payment->backType !== null) {
             $backId = md5(time() . rand());
             $currSrv = new CurrenciesService();
             $defaultCurrencyId = $currSrv->getDefault()->id;
             $stmtPay->bindParam(":id", $backId);
             $stmtPay->bindParam(":type", $payment->backType);
             $stmtPay->bindParam(":amount", $payment->backAmount);
             $stmtPay->bindParam(":currId", $defaultCurrencyId);
             $stmtPay->bindParam(":currAmount", $payment->backAmount);
             $stmtPay->bindValue(":pair", $paymentId);
             // :rcptId is already bound
             if ($stmtPay->execute() === false) {
                 if ($newTransaction) {
                     $pdo->rollback();
                 }
                 return false;
             }
         }
         // Check prepaid
         if ($payment->type == 'prepaid') {
             $custSrv = new CustomersService();
             $ok = $custSrv->addPrepaid($ticket->customerId, $payment->amount * -1);
             if ($ok === false) {
                 if ($newTransaction) {
                     $pdo->rollback();
                 }
                 return false;
             }
         } else {
             if ($payment->type == "debt") {
                 // Debtpaid is a negative total of all payments
                 $custSrv = new CustomersService();
                 $ok = $custSrv->addDebt($ticket->customerId, $payment->amount, $ticket->date);
                 if ($ok === false) {
                     if ($newTransaction) {
                         $pdo->rollback();
                     }
                     return false;
                 }
             } else {
                 if ($payment->type == "debtpaid") {
                     // Debtpaid is a negative total of all payments
                     $custSrv = new CustomersService();
                     $ok = $custSrv->recoverDebt($ticket->customerId, $payment->amount * -1);
                     if ($ok === false) {
                         if ($newTransaction) {
                             $pdo->rollback();
                         }
                         return false;
                     }
                 }
             }
         }
     }
     // Insert taxlines
     $stmtTax = $pdo->prepare("INSERT INTO TAXLINES (ID, RECEIPT, TAXID, " . "BASE, AMOUNT)  VALUES (:id, :rcptId, " . ":taxId, :base, :amount)");
     foreach ($ticket->getTaxAmounts() as $ta) {
         $taxId = md5(time() . rand());
         $stmtTax->bindParam(":id", $taxId);
         $stmtTax->bindParam(":rcptId", $id);
         $stmtTax->bindParam(":taxId", $ta->taxId);
         $stmtTax->bindParam(":base", $ta->base);
         $stmtTax->bindParam(":amount", $ta->getAmount());
         if ($stmtTax->execute() === false) {
             if ($newTransaction) {
                 $pdo->rollback();
             }
             return false;
         }
     }
     if ($newTransaction) {
         $pdo->commit();
     }
     return $id;
 }