public function saveFromBasket(Basket $basket) { $transaction = $this->getDb()->beginTransaction(); try { $this->due_amount = $basket->getTotalDue(false); if (!$this->save()) { throw new \RuntimeException('Could not save order model'); } foreach ($basket->getItems(Basket::ITEM_PRODUCT) as $item) { $model = new OrderLine(['order_id' => $this->id, 'product_id' => $item->id, 'quantity' => $item->basketQuantity, 'due_amount' => $item->totalPrice]); if (!$model->save()) { throw new \RuntimeException('Could not save order line model'); } } $transaction->commit(); } catch (\Exception $exception) { $transaction->rollback(); throw $exception; } }
/** * \brief Update a line in database * \param rowid Id of line to update * \param desc Description de la ligne * \param pu Prix unitaire * \param qty Quantity * \param remise_percent Pourcentage de remise de la ligne * \param tva_tx Taux TVA * \param txlocaltax1 Local tax 1 rate * \param txlocaltax2 Local tax 2 rate * \param price_base_type HT or TTC * \param info_bits Miscellanous informations on line * \param date_start Start date of the line * \param date_end End date of the line * \param type Type of line (0=product, 1=service) * \return int < 0 si erreur, > 0 si ok */ function updateline($rowid, $desc, $pu, $qty, $remise_percent = 0, $txtva, $txlocaltax1 = 0, $txlocaltax2 = 0, $price_base_type = 'HT', $info_bits = 0, $date_start = '', $date_end = '', $type = 0, $fk_parent_line = 0, $skip_update_total = 0) { global $conf; dol_syslog("CustomerOrder::UpdateLine {$rowid}, {$desc}, {$pu}, {$qty}, {$remise_percent}, {$txtva}, {$txlocaltax1}, {$txlocaltax2}, {$price_base_type}, {$info_bits}, {$date_start}, {$date_end}, {$type}"); include_once DOL_DOCUMENT_ROOT . '/lib/price.lib.php'; if ($this->brouillon) { $this->db->begin(); // Clean parameters if (empty($qty)) { $qty = 0; } if (empty($info_bits)) { $info_bits = 0; } if (empty($txtva)) { $txtva = 0; } if (empty($txlocaltax1)) { $txlocaltax1 = 0; } if (empty($txlocaltax2)) { $txlocaltax2 = 0; } if (empty($remise)) { $remise = 0; } if (empty($remise_percent)) { $remise_percent = 0; } $remise_percent = price2num($remise_percent); $qty = price2num($qty); $pu = price2num($pu); $txtva = price2num($txtva); $txlocaltax1 = price2num($txtlocaltax1); $txlocaltax2 = price2num($txtlocaltax2); // Calcul du total TTC et de la TVA pour la ligne a partir de // qty, pu, remise_percent et txtva // TRES IMPORTANT: C'est au moment de l'insertion ligne qu'on doit stocker // la part ht, tva et ttc, et ce au niveau de la ligne qui a son propre taux tva. $tabprice = calcul_price_total($qty, $pu, $remise_percent, $txtva, $txlocaltax1, $txlocaltax2, 0, $price_base_type, $info_bits); $total_ht = $tabprice[0]; $total_tva = $tabprice[1]; $total_ttc = $tabprice[2]; $total_localtax1 = $tabprice[9]; $total_localtax2 = $tabprice[10]; // Anciens indicateurs: $price, $subprice, $remise (a ne plus utiliser) $price = $pu; $subprice = $pu; $remise = 0; if ($remise_percent > 0) { $remise = round($pu * $remise_percent / 100, 2); $price = $pu - $remise; } // Update line $this->line = new OrderLine($this->db); // Stock previous line records $staticline = new OrderLine($this->db); $staticline->fetch($rowid); $this->line->oldline = $staticline; $this->line->rowid = $rowid; $this->line->desc = $desc; $this->line->qty = $qty; $this->line->tva_tx = $txtva; $this->line->localtax1_tx = $txlocaltax1; $this->line->localtax2_tx = $txlocaltax2; $this->line->remise_percent = $remise_percent; $this->line->subprice = $subprice; $this->line->info_bits = $info_bits; $this->line->total_ht = $total_ht; $this->line->total_tva = $total_tva; $this->line->total_localtax1 = $total_localtax1; $this->line->total_localtax2 = $total_localtax2; $this->line->total_ttc = $total_ttc; $this->line->date_start = $date_start; $this->line->date_end = $date_end; $this->line->product_type = $type; $this->line->fk_parent_line = $fk_parent_line; $this->line->skip_update_total = $skip_update_total; // TODO deprecated $this->line->price = $price; $this->line->remise = $remise; $result = $this->line->update(); if ($result > 0) { // Mise a jour info denormalisees $this->update_price(1); $this->db->commit(); return $result; } else { $this->error = $this->db->error(); $this->db->rollback(); dol_syslog("CustomerOrder::UpdateLine Error=" . $this->error, LOG_ERR); return -1; } } else { $this->error = "CustomerOrder::Updateline Order status makes operation forbidden"; return -2; } }
/** * Add a expedition line. * If STOCK_WAREHOUSE_NOT_REQUIRED_FOR_SHIPMENTS is set, you can add a shipment line, with no stock source defined * If STOCK_MUST_BE_ENOUGH_FOR_SHIPMENT is not set, you can add a shipment line, even if not enough into stock * * @param int $entrepot_id Id of warehouse * @param int $id Id of source line (order line) * @param int $qty Quantity * @param array $array_options extrafields array * @return int <0 if KO, >0 if OK */ function addline($entrepot_id, $id, $qty, $array_options = 0) { global $conf, $langs; $num = count($this->lines); $line = new ExpeditionLigne($this->db); $line->entrepot_id = $entrepot_id; $line->origin_line_id = $id; $line->qty = $qty; $orderline = new OrderLine($this->db); $orderline->fetch($id); if (!empty($conf->stock->enabled) && !empty($orderline->fk_product)) { $fk_product = $orderline->fk_product; if (!($entrepot_id > 0) && empty($conf->global->STOCK_WAREHOUSE_NOT_REQUIRED_FOR_SHIPMENTS)) { $langs->load("errors"); $this->error = $langs->trans("ErrorWarehouseRequiredIntoShipmentLine"); return -1; } if ($conf->global->STOCK_MUST_BE_ENOUGH_FOR_SHIPMENT) { // Check must be done for stock of product into warehouse if $entrepot_id defined $product = new Product($this->db); $result = $product->fetch($fk_product); $product_type = $product->type; if ($entrepot_id > 0) { $product->load_stock(); $product_stock = $product->stock_warehouse[$entrepot_id]->real; } else { $product_stock = $product->stock_reel; } if ($product_type == 0 && $product_stock < $qty) { $this->error = $langs->trans('ErrorStockIsNotEnough'); $this->db->rollback(); return -3; } } } // extrafields if (empty($conf->global->MAIN_EXTRAFIELDS_DISABLED) && is_array($array_options) && count($array_options) > 0) { // For avoid conflicts if trigger used $line->array_options = $array_options; } $this->lines[$num] = $line; }
/** * Update a line in database * * @param int $rowid Id of line to update * @param string $desc Description de la ligne * @param float $pu Prix unitaire * @param float $qty Quantity * @param float $remise_percent Pourcentage de remise de la ligne * @param float $txtva Taux TVA * @param float $txlocaltax1 Local tax 1 rate * @param float $txlocaltax2 Local tax 2 rate * @param string $price_base_type HT or TTC * @param int $info_bits Miscellaneous informations on line * @param int $date_start Start date of the line * @param int $date_end End date of the line * @param int $type Type of line (0=product, 1=service) * @param int $fk_parent_line Id of parent line (0 in most cases, used by modules adding sublevels into lines). * @param int $skip_update_total Keep fields total_xxx to 0 (used for special lines by some modules) * @param int $fk_fournprice Id of origin supplier price * @param int $pa_ht Price (without tax) of product when it was bought * @param string $label Label * @param int $special_code Special code (also used by externals modules!) * @param array $array_options extrafields array * @param string $fk_unit Code of the unit to use. Null to use the default one * @return int < 0 if KO, > 0 if OK */ function updateline($rowid, $desc, $pu, $qty, $remise_percent, $txtva, $txlocaltax1 = 0.0, $txlocaltax2 = 0.0, $price_base_type = 'HT', $info_bits = 0, $date_start = '', $date_end = '', $type = 0, $fk_parent_line = 0, $skip_update_total = 0, $fk_fournprice = null, $pa_ht = 0, $label = '', $special_code = 0, $array_options = 0, $fk_unit = null) { global $conf, $mysoc; dol_syslog(get_class($this) . "::updateline id={$rowid}, desc={$desc}, pu={$pu}, qty={$qty}, remise_percent={$remise_percent}, txtva={$txtva}, txlocaltax1={$txlocaltax1}, txlocaltax2={$txlocaltax2}, price_base_type={$price_base_type}, info_bits={$info_bits}, date_start={$date_start}, date_end={$date_end}, type={$type}, fk_parent_line={$fk_parent_line}, pa_ht={$pa_ht}, special_code={$special_code}"); include_once DOL_DOCUMENT_ROOT . '/core/lib/price.lib.php'; if (!empty($this->brouillon)) { $this->db->begin(); // Clean parameters if (empty($qty)) { $qty = 0; } if (empty($info_bits)) { $info_bits = 0; } if (empty($txtva)) { $txtva = 0; } if (empty($txlocaltax1)) { $txlocaltax1 = 0; } if (empty($txlocaltax2)) { $txlocaltax2 = 0; } if (empty($remise)) { $remise = 0; } if (empty($remise_percent)) { $remise_percent = 0; } if (empty($special_code) || $special_code == 3) { $special_code = 0; } $remise_percent = price2num($remise_percent); $qty = price2num($qty); $pu = price2num($pu); $pa_ht = price2num($pa_ht); $txtva = price2num($txtva); $txlocaltax1 = price2num($txlocaltax1); $txlocaltax2 = price2num($txlocaltax2); // Calcul du total TTC et de la TVA pour la ligne a partir de // qty, pu, remise_percent et txtva // TRES IMPORTANT: C'est au moment de l'insertion ligne qu'on doit stocker // la part ht, tva et ttc, et ce au niveau de la ligne qui a son propre taux tva. $localtaxes_type = getLocalTaxesFromRate($txtva, 0, $this->thirdparty, $mysoc); $txtva = preg_replace('/\\s*\\(.*\\)/', '', $txtva); // Remove code into vatrate. $tabprice = calcul_price_total($qty, $pu, $remise_percent, $txtva, $txlocaltax1, $txlocaltax2, 0, $price_base_type, $info_bits, $type, $mysoc, $localtaxes_type); $total_ht = $tabprice[0]; $total_tva = $tabprice[1]; $total_ttc = $tabprice[2]; $total_localtax1 = $tabprice[9]; $total_localtax2 = $tabprice[10]; // Anciens indicateurs: $price, $subprice, $remise (a ne plus utiliser) $price = $pu; $subprice = $pu; $remise = 0; if ($remise_percent > 0) { $remise = round($pu * $remise_percent / 100, 2); $price = $pu - $remise; } //Fetch current line from the database and then clone the object and set it in $oldline property $line = new OrderLine($this->db); $line->fetch($rowid); $staticline = clone $line; $line->oldline = $staticline; $this->line = $line; $this->line->context = $this->context; // Reorder if fk_parent_line change if (!empty($fk_parent_line) && !empty($staticline->fk_parent_line) && $fk_parent_line != $staticline->fk_parent_line) { $rangmax = $this->line_max($fk_parent_line); $this->line->rang = $rangmax + 1; } $this->line->rowid = $rowid; $this->line->label = $label; $this->line->desc = $desc; $this->line->qty = $qty; $this->line->tva_tx = $txtva; $this->line->localtax1_tx = $txlocaltax1; $this->line->localtax2_tx = $txlocaltax2; $this->line->localtax1_type = $localtaxes_type[0]; $this->line->localtax2_type = $localtaxes_type[2]; $this->line->remise_percent = $remise_percent; $this->line->subprice = $subprice; $this->line->info_bits = $info_bits; $this->line->special_code = $special_code; $this->line->total_ht = $total_ht; $this->line->total_tva = $total_tva; $this->line->total_localtax1 = $total_localtax1; $this->line->total_localtax2 = $total_localtax2; $this->line->total_ttc = $total_ttc; $this->line->date_start = $date_start; $this->line->date_end = $date_end; $this->line->product_type = $type; $this->line->fk_parent_line = $fk_parent_line; $this->line->skip_update_total = $skip_update_total; $this->line->fk_unit = $fk_unit; $this->line->fk_fournprice = $fk_fournprice; $this->line->pa_ht = $pa_ht; // TODO deprecated $this->line->price = $price; $this->line->remise = $remise; if (is_array($array_options) && count($array_options) > 0) { $this->line->array_options = $array_options; } $result = $this->line->update(); if ($result > 0) { // Reorder if child line if (!empty($fk_parent_line)) { $this->line_order(true, 'DESC'); } // Mise a jour info denormalisees $this->update_price(1); $this->db->commit(); return $result; } else { $this->error = $this->line->error; $this->db->rollback(); return -1; } } else { $this->error = get_class($this) . "::updateline Order status makes operation forbidden"; $this->errors = array('OrderStatusMakeOperationForbidden'); return -2; } }
/** * Add a expedition line. * If STOCK_WAREHOUSE_NOT_REQUIRED_FOR_SHIPMENTS is set, you can add a shipment line, with no stock source defined * If STOCK_MUST_BE_ENOUGH_FOR_SHIPMENT is not set, you can add a shipment line, even if not enough into stock * * @param int $entrepot_id Id of warehouse * @param int $id Id of source line (order line) * @param int $qty Quantity * @return int <0 if KO, >0 if OK */ function addline($entrepot_id, $id, $qty) { global $conf, $langs; $num = count($this->lines); $line = new ExpeditionLigne($this->db); $line->entrepot_id = $entrepot_id; $line->origin_line_id = $id; $line->qty = $qty; $orderline = new OrderLine($this->db); $orderline->fetch($id); if (!empty($conf->stock->enabled) && !empty($orderline->fk_product)) { $fk_product = $orderline->fk_product; if (!($entrepot_id > 0) && empty($conf->global->STOCK_WAREHOUSE_NOT_REQUIRED_FOR_SHIPMENTS)) { $this->error = $langs->trans("ErrorWarehouseRequiredIntoShipmentLine"); return -1; } if ($conf->global->STOCK_MUST_BE_ENOUGH_FOR_SHIPMENT) { $product = new Product($this->db); $result = $product->fetch($fk_product); $product_type = $product->type; if ($product_type == 0 && $product->stock_reel < $qty) { $this->error = $langs->trans('ErrorStockIsNotEnough'); $this->db->rollback(); return -3; } } } $this->lines[$num] = $line; }
public function testBuyingProcess() { /*var sale = new Accountability.ConnectedAccountabilityType('SaleAgreement'); var seller = new Accountability.PartyType('Vendor'); var buyer = new Accountability.PartyType('Customer'); sale.addConnectionRule(buyer, seller); var alex = new Accountability.Party("Alex Mbaka", buyer); var pablo = new Accountability.Party("Pablo Gift Shop", seller); accountabilityInstances.push(Accountability.Accountability.create(alex, pablo, sale));*/ /*$sale = new ConnectedAccountabilityType('SaleAgreement');*/ //oR this which is a more specialized version that defines party and party type in one process $ii = StockInventory::GetItem(15); $ii2 = StockInventory::GetItem(25); //from view model $this->assertInstanceOf('StockAccount', $ii); $orderItem = OrderLine::Create(ShoppingSession::GetOrderId(), $ii->item->itemId, $ii->item->name, 2, $ii->taxcode, $ii->retail_price, $ii->cost_price, 0); $orderItem2 = OrderLine::Create(ShoppingSession::GetOrderId(), $ii2->item->itemId, $ii2->item->name, 1, $ii2->taxcode, $ii2->retail_price, $ii2->cost_price, 0); //$catalogObj = Catalog::GetCatalogItem('ID345625'); gets item category too //static variables initialized on init ShoppingSession::AddToTestCart($orderItem); //date and time ShoppingSession::AddToTestCart($orderItem2); //adds order item to the sale agreement particulars //reduce goods for sale temporarily #### WHEN THE USER POSTS SHOPPING DETAILS - i.e. customer, shopping order, and recepient of goods $sale = new SimpleSaleAccountability(); $customer = new Customer(2, 'Alex Mbaka', '0727596626', '*****@*****.**', 'Suite 602, Marafique Arcade. Kenyatta Avenue', 'Thika, KIAMBU', 'Kenya'); $vendor = Vendor::GetVendor(); //Pablo Gift Shop //Opens New (Obligations account and) Income/Expenditure Account //Links to party account $sale->setBuyer($customer); // -- vendor is automatically set $sale->setSeller($vendor); $cart = ShoppingSession::CompleteSession(); //for simple sales $sale->initialize($cart->order); //$sale->addOrder($cart->order); -- for more complex sales #DEFERRED ORDERING - ADD TO WISH LIST //$customer->addToWishList($sale->order); $customer->authorizeOrder($sale->order); //generates invoice by communicating with the transaction core //client object receives new Invoice $amount = new Money('35040.00', Currency::Get('KES')); //new Quantity('number', 'unit') //$signature = new Signature('Name/email','Password/Identification/SessionID'); $payment = new PaypalPayment('Email', 'REFERENCES', $amount); //$payment = new Payment('Customer', 'STATIC Vendor', $amount, $paymentmethod); //$destination = new Location('Name of Building', 'Town', 'County', 'Country', 'Physical Address/Closest road and or stage', 'Area Code', 'Latitude', 'Longitude'); //$paymentmethod->authorizePayment($payee, $amount); //verify name and identification/password is the same as that in client record/session //when singleton object is in use there is a status property thats either busy or ready //generate invoive then get it //$invoice = $sale->getInvoice(); if ($sale->getInvoice()) { $receipt = $customer->makePayment($sale->invoice, $payment); $this->assertInstanceOf('Receipt', $receipt); } //move money to sales revenue account with timestamp to map values on graph //client receives receipt via observer mechanism i.e call on receivereceipt method on the client object that is configured to send emails on demand //assert balance history that the client has been billed and revenues have been received $this->assertInstanceOf('Accountability', $sale); //throw new Exception("That's not a server name!"); }
/** * Mise a jour des totaux lignes de commande * * @param DoliDB $db Database handler * @param Translate $langs Object langs * @param Conf $conf Object conf * @return void */ function migrate_price_commande($db, $langs, $conf) { $db->begin(); print '<tr><td colspan="4">'; print '<br>'; print '<b>' . $langs->trans('MigrationOrder') . "</b><br>\n"; // Liste des lignes commande non a jour $sql = "SELECT cd.rowid, cd.qty, cd.subprice, cd.remise_percent, cd.tva_tx as tva_taux, cd.info_bits,"; $sql .= " c.rowid as commandeid, c.remise_percent as remise_percent_global"; $sql .= " FROM " . MAIN_DB_PREFIX . "commandedet as cd, " . MAIN_DB_PREFIX . "commande as c"; $sql .= " WHERE cd.fk_commande = c.rowid"; $sql .= " AND ((cd.total_ttc = 0 AND cd.remise_percent != 100) or cd.total_ttc IS NULL)"; dolibarr_install_syslog("upgrade2::migrate_price_commande", LOG_DEBUG); $resql = $db->query($sql); if ($resql) { $num = $db->num_rows($resql); $i = 0; if ($num) { while ($i < $num) { $obj = $db->fetch_object($resql); $rowid = $obj->rowid; $qty = $obj->qty; $pu = $obj->subprice; $txtva = $obj->tva_taux; $remise_percent = $obj->remise_percent; $remise_percent_global = $obj->remise_percent_global; $info_bits = $obj->info_bits; // On met a jour les 3 nouveaux champs $commandeligne = new OrderLine($db); $commandeligne->fetch($rowid); $result = calcul_price_total($qty, $pu, $remise_percent, $txtva, 0, 0, $remise_percent_global, 'HT', $info_bits, 0); $total_ht = $result[0]; $total_tva = $result[1]; $total_ttc = $result[2]; $commandeligne->total_ht = $total_ht; $commandeligne->total_tva = $total_tva; $commandeligne->total_ttc = $total_ttc; dolibarr_install_syslog("upgrade2: Line {$rowid}: commandeid={$obj->rowid} pu={$pu} qty={$qty} tva_taux={$txtva} remise_percent={$remise_percent} remise_global={$remise_percent_global} -> {$total_ht}, {$total_tva}, {$total_ttc}"); print ". "; $commandeligne->update_total(); /* On touche pas a facture mere $commande = new Commande($db); $commande->id = $obj->rowid; if ( $commande->fetch($commande->id) >= 0 ) { if ( $commande->update_price() > 0 ) { print ". "; } else { print "Error id=".$commande->id; } } else { print "Error #3"; } */ $i++; } } else { print $langs->trans("AlreadyDone"); } $db->free($resql); /* $sql = "DELETE FROM ".MAIN_DB_PREFIX."commandedet"; $sql.= " WHERE price = 0 and total_ttc = 0 and total_tva = 0 and total_ht = 0 AND remise_percent = 0"; $resql=$db->query($sql); if (! $resql) { dol_print_error($db); } */ $db->commit(); } else { print "Error #1 " . $db->error(); $db->rollback(); } print '<br>'; print '</td></tr>'; }
$com->source = 1; $com->remise_percent = 0; $result = $user->fetch($userid); $idobject = $com->create($user); $db->commit(); $db->query("UPDATE " . MAIN_DB_PREFIX . "commande SET ref='Place-{$place}' WHERE rowid={$idobject};"); $db->commit(); $placeid = $idobject; for ($i = 1; $i <= count($id); $i++) { $prod = new Product($db); $prod->fetch($id[$i - 1]); if ($prod->tva_tx < 1) { $prod->tva_tx = 21; } $vatmult = $prod->tva_tx / 100 + 1; $com = new OrderLine($db); $com->fk_commande = $placeid; $com->qty = $qty[$i - 1]; $com->tva_tx = $prod->tva_tx; $com->fk_product = $id[$i - 1]; $com->subprice = round($price[$i - 1] / $vatmult * 100) / 100; $com->label = $label[$i - 1]; $com->rang = '1'; $com->remise_percent = $dto[$i - 1]; $com->remise = round($price[$i - 1] * $qty[$i - 1] * $dto[$i - 1]) / 100; $com->total_ttc = round(($qty[$i - 1] * $price[$i - 1] - $com->remise) * 100) / 100; $com->total_ht = round($com->total_ttc / $vatmult * 100) / 100; $com->fk_parent_line = ''; $com->total_tva = $com->total_ttc - $com->total_ht; $com->pa_ht = '1'; $com->price = $price[$i - 1];
public static function GetOrderItems($orderId) { //check whether available and make necessary inventory deductions, then $lineItems = array(); try { $sql = 'SELECT * FROM order_items WHERE order_id = ' . $orderId; $res = DatabaseHandler::GetAll($sql); foreach ($res as $item) { $lineItem = new OrderLine($item['order_id'], $item['item_id'], $item['item_name'], $item['quantity'], $item['vat'], $item['unit_price'], $item['unit_cost'], $item['discount'], $item['status']); $lineItem->initId($item['id']); $lineItems[] = $lineItem; } return $lineItems; } catch (Exception $e) { } }
public function run() { Order::create(['user_id' => 1, 'address_id' => 1, 'card_id' => 1, 'status' => 0]); OrderLine::create(['order_id' => 1, 'product_id' => 1, 'size' => 6]); }
/** * Add a expedition line * * @param int $entrepot_id Id of warehouse * @param int $id Id of source line * @param int $qty Quantity * @return int <0 if KO, >0 if OK */ function addline($entrepot_id, $id, $qty) { global $conf, $langs; $num = count($this->lines); $line = new ExpeditionLigne($this->db); $line->entrepot_id = $entrepot_id; $line->origin_line_id = $id; $line->qty = $qty; if ($conf->global->STOCK_MUST_BE_ENOUGH_FOR_SHIPMENT) { $orderline = new OrderLine($this->db); $orderline->fetch($id); $fk_product = $orderline->fk_product; if (!empty($orderline->fk_product)) { $product = new Product($this->db); $result = $product->fetch($fk_product); $product_type = $product->type; if ($product_type == 0 && $product->stock_reel < $qty) { $this->error = $langs->trans('ErrorStockIsNotEnough'); $this->db->rollback(); return -3; } } } $this->lines[$num] = $line; }