/** * Add ticket line into database (linked to product/service or not) * @param array $lines Ticket Lines * @return array Result of adding */ private function addFactureLines($lines, $idTicket, $isreturn = false) { global $db; $res = 0; $object = new Facture($db); $object->fetch($idTicket); $object->brouillon = 1; if (sizeof($lines) > 0) { foreach ($lines as $line) { if (sizeof($line) > 0) { if ($line['idProduct'] > 0) { $product_static = new Product($db); $product_static->id = $line['idProduct']; $product_static->load_stock(); if ($product_static->stock_reel < 1 || $product_static->stock_reel < $line['cant']) { $res = -4; } if (!$isreturn) { $qty = $line['cant']; } else { $qty = $line['cant'] * -1; } $object->brouillon = 1; $line['discount'] = $line['discount'] + $object->remise_percent; $line['description'] = $line['description'] . " " . $line['note']; // TODO buscar el pmp del producto para este almacén, si es cero, pmp en general. $terminal = $_SESSION['TERMINAL_ID']; $cash = new Cash($db); $cash->fetch($terminal); $warehouse = $cash->fk_warehouse; $sql = "SELECT\tp.pmp as totpmp, (select ps.pmp FROM " . MAIN_DB_PREFIX . "product_stock as ps "; $sql .= " WHERE ps.fk_product = " . $line["idProduct"] . " AND ps.fk_entrepot = " . $warehouse . ") as warepmp "; $sql .= " FROM " . MAIN_DB_PREFIX . "product as p WHERE p.rowid = " . $line["idProduct"]; $resql = $db->query($sql); if ($resql) { $objp = $db->fetch_object($resql); $pmp = $objp->warepmp; if ($pmp <= 0) { $pmp = $objp->totpmp; if ($pmp <= 0 && $conf->global->ForceBuyingPriceIfNull) { $pmp = $line['price']; } } } $res = $object->addline($line['description'], $line['price'], $qty, $line['tva_tx'], $line['localtax1_tx'], $line['localtax2_tx'], $line['idProduct'], $line['discount'], '', '', 0, 0, '', $line['price_base_type'], $line['price_ttc'], $line['fk_product_type'], -1, 0, '', 0, 0, null, $pmp); } } else { $res = -1; } } } return $res; }
$errmsgs = $invoice->errors; $error++; } } if (!$error) { // Add line to draft invoice $idprodsubscription = 0; if (!empty($conf->global->ADHERENT_PRODUCT_ID_FOR_SUBSCRIPTIONS) && (!empty($conf->product->enabled) || !empty($conf->service->enabled))) { $idprodsubscription = $conf->global->ADHERENT_PRODUCT_ID_FOR_SUBSCRIPTIONS; } $vattouse = 0; if (isset($conf->global->ADHERENT_VAT_FOR_SUBSCRIPTIONS) && $conf->global->ADHERENT_VAT_FOR_SUBSCRIPTIONS == 'defaultforfoundationcountry') { $vattouse = get_default_tva($mysoc, $mysoc, $idprodsubscription); } //print xx".$vattouse." - ".$mysoc." - ".$customer;exit; $result = $invoice->addline($label, 0, 1, $vattouse, 0, 0, $idprodsubscription, 0, $datecotisation, $datesubend, 0, 0, '', 'TTC', $cotisation, 1); if ($result <= 0) { $errmsg = $invoice->error; $error++; } } if (!$error) { // Validate invoice $result = $invoice->validate($user); if ($result <= 0) { $errmsg = $invoice->error; $errmsgs = $invoice->errors; $error++; } } // Add payment onto invoice
} else { $pu_ttc = price2num($pu_ht * (1 + ($tva_tx/100)), 'MU'); } } $result = $facture->addline($facture->id, $desc, $pu_ht, $_POST["qty"], $tva_tx, $localtax1_tx, $localtax2_tx, $prod->id, $_POST["remise_percent"], '', '', '', '', '', $price_base_type, $pu_ttc ); if ($result > 0) { Header("Location: ".DOL_URL_ROOT."/compta/facture.php?facid=".$facture->id); exit; } }
} if (GETPOST('propalid') > 0) { $result = $propal->addline($desc, $pu_ht, GETPOST('qty'), $tva_tx, $localtax1_tx, $localtax2_tx, $object->id, GETPOST('remise_percent'), $price_base_type, $pu_ttc, 0, 0, -1, 0, 0, 0, 0, '', '', '', 0, $object->fk_unit); if ($result > 0) { header("Location: " . DOL_URL_ROOT . "/comm/propal.php?id=" . $propal->id); return; } setEventMessages($langs->trans("ErrorUnknown") . ": {$result}", null, 'errors'); } elseif (GETPOST('commandeid') > 0) { $result = $commande->addline($desc, $pu_ht, GETPOST('qty'), $tva_tx, $localtax1_tx, $localtax2_tx, $object->id, GETPOST('remise_percent'), '', '', $price_base_type, $pu_ttc, '', '', 0, -1, 0, 0, null, 0, '', 0, $object->fk_unit); if ($result > 0) { header("Location: " . DOL_URL_ROOT . "/commande/card.php?id=" . $commande->id); exit; } } elseif (GETPOST('factureid') > 0) { $result = $facture->addline($desc, $pu_ht, GETPOST('qty'), $tva_tx, $localtax1_tx, $localtax2_tx, $object->id, GETPOST('remise_percent'), '', '', '', '', '', $price_base_type, $pu_ttc, Facture::TYPE_STANDARD, -1, 0, '', 0, 0, null, 0, '', 0, 100, '', $object->fk_unit); if ($result > 0) { header("Location: " . DOL_URL_ROOT . "/compta/facture.php?facid=" . $facture->id); exit; } } } else { $action = ""; setEventMessages($langs->trans("WarningSelectOneDocument"), null, 'warnings'); } } } /* * View */ $helpurl = '';
$i = 0; $result = 0; while ($i < GEN_NUMBER_FACTURE && $result >= 0) { $i++; $socid = rand(1, $num_socs); print "Invoice " . $i . " for socid " . $socid; $facture = new Facture($db, $socids[$socid]); $facture->date = time(); $facture->cond_reglement_id = 3; $facture->mode_reglement_id = 3; $result = $facture->create($user); if ($result >= 0) { $result = $facture->validate($user); if ($result) { $nbp = rand(2, 5); $xnbp = 0; while ($xnbp < $nbp) { $prodid = rand(1, $num_prods); $product = new Product($db); $result = $product->fetch($prodids[$prodid]); $result = $facture->addline($facture->id, $product->description, $product->price, rand(1, 5), 0, 0, 0, $prodids[$prodid], 0, '', '', 0, 0, '', $product->price_base_type, $product->price_ttc, $product->type); $xnbp++; } print " OK with ref " . $facture->ref . "\n"; } else { dol_print_error($db, $facture->error); } } else { dol_print_error($db, $facture->error); } }
//Date end $date_end = false; if ($lines[$i]->date_fin_prevue) { $date_end = $lines[$i]->date_fin_prevue; } if ($lines[$i]->date_fin_reel) { $date_end = $lines[$i]->date_fin_reel; } if ($lines[$i]->date_end) { $date_end = $lines[$i]->date_end; } // Reset fk_parent_line for no child products and special product if ($lines[$i]->product_type != 9 && empty($lines[$i]->fk_parent_line) || $lines[$i]->product_type == 9) { $fk_parent_line = 0; } $result = $object->addline($desc, $lines[$i]->subprice, $lines[$i]->qty, $lines[$i]->tva_tx, $lines[$i]->localtax1_tx, $lines[$i]->localtax2_tx, $lines[$i]->fk_product, $lines[$i]->remise_percent, $date_start, $date_end, 0, $lines[$i]->info_bits, $lines[$i]->fk_remise_except, 'HT', 0, $product_type, $ii, $lines[$i]->special_code, $object->origin, $lines[$i]->rowid, $fk_parent_line, $lines[$i]->fk_fournprice, $lines[$i]->pa_ht, $lines[$i]->label); if ($result > 0) { $lineid = $result; } else { $lineid = 0; $error++; break; } // Defined the new fk_parent_line if ($result > 0 && $lines[$i]->product_type == 9) { $fk_parent_line = $result; } } } } else { setEventMessages($objectsrc->error, $objectsrc->errors, 'errors');
/** * Test function addline and update_price * * @return boolean * @see http://wiki.dolibarr.org/index.php/Draft:VAT_calculation_and_rounding#Standard_usage */ public function testUpdatePrice() { //$this->sharedFixture global $conf, $user, $langs, $db; $this->savconf = $conf; $this->savuser = $user; $this->savlangs = $langs; $this->savdb = $db; $conf->global->MAIN_ROUNDOFTOTAL_NOT_TOTALOFROUND = 0; // Two lines of 1.24 give 2.48 HT and 2.72 TTC with standard vat rounding mode $localobject = new Facture($this->savdb); $localobject->initAsSpecimen('nolines'); $invoiceid = $localobject->create($user); $localobject->addline('Desc', 1.24, 1, 10, 0, 0, 0, 0, '', '', 0, 0, 0, 'HT'); $localobject->addline('Desc', 1.24, 1, 10, 0, 0, 0, 0, '', '', 0, 0, 0, 'HT'); $newlocalobject = new Facture($this->savdb); $newlocalobject->fetch($invoiceid); $this->assertEquals(2.48, $newlocalobject->total_ht, "testUpdatePrice test1"); $this->assertEquals(0.24, $newlocalobject->total_tva, "testUpdatePrice test2"); $this->assertEquals(2.72, $newlocalobject->total_ttc, "testUpdatePrice test3"); // Two lines of 1.24 give 2.48 HT and 2.73 TTC with global vat rounding mode $localobject = new Facture($this->savdb); $localobject->initAsSpecimen('nolines'); $invoiceid = $localobject->create($user); $localobject->addline('Desc', 1.24, 1, 10, 0, 0, 0, 0, '', '', 0, 0, 0, 'HT'); $localobject->addline('Desc', 1.24, 1, 10, 0, 0, 0, 0, '', '', 0, 0, 0, 'HT'); $newlocalobject = new Facture($this->savdb); $newlocalobject->fetch($invoiceid); $this->assertEquals(2.48, $newlocalobject->total_ht, "testUpdatePrice test4"); //$this->assertEquals(0.25,$newlocalobject->total_tva); //$this->assertEquals(2.73,$newlocalobject->total_ttc); }
static function createFactureFromObject(&$object) { global $db, $conf, $user, $langs; dol_include_once('/compta/facture/class/facture.class.php'); $langs->load('grapefruit@grapefruit'); $dateinvoice = dol_mktime(0, 0, 0, date('m'), date('d'), date('Y')); $f = new Facture($db); $f->socid = $object->socid; $f->type = Facture::TYPE_STANDARD; $f->number = $_POST['facnumber']; $f->date = $dateinvoice; $f->note_public = $object->note_public; $f->note_private = $object->note_private; $f->ref_client = $object->ref_client; $f->fk_project = $object->fk_project; $f->cond_reglement_id = $object->cond_reglement_id; $f->mode_reglement_id = $object->mode_reglement_id; $origin = 'commande'; $originid = $object->id; $f->linked_objects[$origin] = $originid; $id = $f->create($user); $lines = $object->lines; if (empty($lines) && method_exists($object, 'fetch_lines')) { $object->fetch_lines(); $lines = $object->lines; } $fk_parent_line = 0; $num = count($lines); for ($i = 0; $i < $num; $i++) { $label = !empty($lines[$i]->label) ? $lines[$i]->label : ''; $desc = !empty($lines[$i]->desc) ? $lines[$i]->desc : $lines[$i]->libelle; if ($f->situation_counter == 1) { $lines[$i]->situation_percent = 0; } if ($lines[$i]->subprice < 0) { // Negative line, we create a discount line $discount = new DiscountAbsolute($db); $discount->fk_soc = $f->socid; $discount->amount_ht = abs($lines[$i]->total_ht); $discount->amount_tva = abs($lines[$i]->total_tva); $discount->amount_ttc = abs($lines[$i]->total_ttc); $discount->tva_tx = $lines[$i]->tva_tx; $discount->fk_user = $user->id; $discount->description = $desc; $discountid = $discount->create($user); if ($discountid > 0) { $result = $f->insert_discount($discountid); // This include link_to_invoice } else { setEventMessages($discount->error, $discount->errors, 'errors'); $error++; break; } } else { // Positive line $product_type = $lines[$i]->product_type ? $lines[$i]->product_type : 0; // Date start $date_start = false; if ($lines[$i]->date_debut_prevue) { $date_start = $lines[$i]->date_debut_prevue; } if ($lines[$i]->date_debut_reel) { $date_start = $lines[$i]->date_debut_reel; } if ($lines[$i]->date_start) { $date_start = $lines[$i]->date_start; } // Date end $date_end = false; if ($lines[$i]->date_fin_prevue) { $date_end = $lines[$i]->date_fin_prevue; } if ($lines[$i]->date_fin_reel) { $date_end = $lines[$i]->date_fin_reel; } if ($lines[$i]->date_end) { $date_end = $lines[$i]->date_end; } // Reset fk_parent_line for no child products and special product if ($lines[$i]->product_type != 9 && empty($lines[$i]->fk_parent_line) || $lines[$i]->product_type == 9) { $fk_parent_line = 0; } // Extrafields if (empty($conf->global->MAIN_EXTRAFIELDS_DISABLED) && method_exists($lines[$i], 'fetch_optionals')) { $lines[$i]->fetch_optionals($lines[$i]->rowid); $array_options = $lines[$i]->array_options; } // View third's localtaxes for now $localtax1_tx = get_localtax($lines[$i]->tva_tx, 1, $f->client); $localtax2_tx = get_localtax($lines[$i]->tva_tx, 2, $f->client); $result = $f->addline($desc, $lines[$i]->subprice, $lines[$i]->qty, $lines[$i]->tva_tx, $localtax1_tx, $localtax2_tx, $lines[$i]->fk_product, $lines[$i]->remise_percent, $date_start, $date_end, 0, $lines[$i]->info_bits, $lines[$i]->fk_remise_except, 'HT', 0, $product_type, $lines[$i]->rang, $lines[$i]->special_code, $f->origin, $lines[$i]->rowid, $fk_parent_line, $lines[$i]->fk_fournprice, $lines[$i]->pa_ht, $label, $array_options, $lines[$i]->situation_percent, $lines[$i]->fk_prev_id, $lines[$i]->fk_unit); if ($result > 0) { $lineid = $result; } else { $lineid = 0; $error++; break; } // Defined the new fk_parent_line if ($result > 0 && $lines[$i]->product_type == 9) { $fk_parent_line = $result; } } } if (empty($error)) { if ($f->validate($user) > 0) { $object->classifyBilled(); // Redirection vers écrand de paiement setEventMessage($langs->trans('BillCreated')); header('Location: ' . dol_buildpath('/compta/paiement.php?action=create&facid=' . $f->id, 1)); } } }
/** * testFactureRoundingCreate2 * * @return int * * @depends testFactureRoundingCreate1 * Test according to page http://wiki.dolibarr.org/index.php/Draft:VAT_calculation_and_rounding#Standard_usage */ public function testFactureRoundingCreate2() { global $conf,$user,$langs,$db; $conf=$this->savconf; $user=$this->savuser; $langs=$this->savlangs; $db=$this->savdb; $localobject=new Facture($this->savdb); $localobject->initAsSpecimen(); $localobject->lines=array(); unset($localobject->total_ht); unset($localobject->total_ttc); unset($localobject->total_vat); $result=$localobject->create($user); // Add two lines for ($i=0; $i<2; $i++) { $localobject->addline($result, 'Description '.$i, 1.24, 1, 10); } $newlocalobject=new Facture($this->savdb); $newlocalobject->fetch($result); //var_dump($newlocalobject); $this->assertEquals($newlocalobject->total_ht, 2.48); //$this->assertEquals($newlocalobject->total_tva, 0.25); //$this->assertEquals($newlocalobject->total_ttc, 2.73); return $result; }
$pu_ttc = price($prodcustprice->lines[0]->price_ttc); $price_base_type = $prodcustprice->lines[0]->price_base_type; $prod->tva_tx = $prodcustprice->lines[0]->tva_tx; } } } // On reevalue prix selon taux tva car taux tva transaction peut etre different // de ceux du produit par defaut (par exemple si pays different entre vendeur et acheteur). if ($tva_tx != $object->tva_tx) { if ($price_base_type != 'HT') { $pu_ht = price2num($pu_ttc / (1 + $tva_tx / 100), 'MU'); } else { $pu_ttc = price2num($pu_ht * (1 + $tva_tx / 100), 'MU'); } } $result = $facture->addline($desc, $pu_ht, GETPOST('qty'), $tva_tx, $localtax1_tx, $localtax2_tx, $object->id, GETPOST('remise_percent'), '', '', '', '', '', $price_base_type, $pu_ttc); if ($result > 0) { header("Location: " . DOL_URL_ROOT . "/compta/facture.php?facid=" . $facture->id); exit; } } } if (GETPOST("cancel") == $langs->trans("Cancel")) { $action = ''; header("Location: " . $_SERVER["PHP_SELF"] . "?id=" . $object->id); exit; } /* * View */ $helpurl = '';
/** * testFactureAddLine3 * * @return void * * @depends testFactureAddLine2 * The depends says test is run only if previous is ok */ public function testFactureAddLine3() { global $conf, $user, $langs, $db; $conf = $this->savconf; $user = $this->savuser; $langs = $this->savlangs; $db = $this->savdb; // With option MAIN_ROUNDOFTOTAL_NOT_TOTALOFROUND = 0 $conf->global->MAIN_ROUNDOFTOTAL_NOT_TOTALOFROUND = 0; $localobject3 = new Facture($this->savdb); $localobject3->initAsSpecimen('nolines'); $facid = $localobject3->create($user); $localobject3->addline('Line 1', 6.36, 3, 21); $localobject3->addline('Line 2', 6.36, 3, 21); $localobject3->addline('Line 3', 6.36, 3, 21); $localobject3->addline('Line 4', 6.36, 3, 21); $localobject3->addline('Line 5', 6.36, 3, 21); print __METHOD__ . " id=" . $facid . " total_ttc=" . $localobject3->total_ttc . "\n"; $this->assertEquals(95.40000000000001, $localobject3->total_ht); $this->assertEquals(20.05, $localobject3->total_tva); $this->assertEquals(115.45, $localobject3->total_ttc); // With option MAIN_ROUNDOFTOTAL_NOT_TOTALOFROUND = 1 $conf->global->MAIN_ROUNDOFTOTAL_NOT_TOTALOFROUND = 1; $localobject3 = new Facture($this->savdb); $localobject3->initAsSpecimen('nolines'); $facid = $localobject3->create($user); $localobject3->addline('Line 1', 6.36, 3, 21); $localobject3->addline('Line 2', 6.36, 3, 21); $localobject3->addline('Line 3', 6.36, 3, 21); $localobject3->addline('Line 4', 6.36, 3, 21); $localobject3->addline('Line 5', 6.36, 3, 21); print __METHOD__ . " id=" . $facid . " total_ttc=" . $localobject3->total_ttc . "\n"; $this->assertEquals(95.40000000000001, $localobject3->total_ht); $this->assertEquals(20.03, $localobject3->total_tva); $this->assertEquals(115.43, $localobject3->total_ttc); }