diff --git a/htdocs/core/menus/standard/eldy.lib.php b/htdocs/core/menus/standard/eldy.lib.php index 83a8f63fee65d317a6ad9a5049e8402c54a7abe4..4a48898b74e4ee9eee67361fe6101efc5b1f96fe 100644 --- a/htdocs/core/menus/standard/eldy.lib.php +++ b/htdocs/core/menus/standard/eldy.lib.php @@ -720,7 +720,8 @@ function print_left_eldy_menu($db,$menu_array_before,$menu_array_after,&$tabMenu if (empty($leftmenu) || $leftmenu=="orders_suppliers") $newmenu->add("/fourn/commande/list.php?leftmenu=orders_suppliers&statut=5", $langs->trans("StatusOrderReceivedAll"), 2, $user->rights->fournisseur->commande->lire); if (empty($leftmenu) || $leftmenu=="orders_suppliers") $newmenu->add("/fourn/commande/list.php?leftmenu=orders_suppliers&statut=6,7", $langs->trans("StatusOrderCanceled"), 2, $user->rights->fournisseur->commande->lire); if (empty($leftmenu) || $leftmenu=="orders_suppliers") $newmenu->add("/fourn/commande/list.php?leftmenu=orders_suppliers&statut=9", $langs->trans("StatusOrderRefused"), 2, $user->rights->fournisseur->commande->lire); - + if (empty($leftmenu) || $leftmenu=="orders_suppliers") $newmenu->add("/fourn/commande/list.php?leftmenu=orders_suppliers&billed=1", $langs->trans("StatusOrderBilled"), 2, $user->rights->fournisseur->commande->lire); + $newmenu->add("/commande/stats/index.php?leftmenu=orders_suppliers&mode=supplier", $langs->trans("Statistics"), 1, $user->rights->fournisseur->commande->lire); } diff --git a/htdocs/fourn/card.php b/htdocs/fourn/card.php index cab8c96b62a144b80c19e14538be990431469683..6613cd8f05cee9ab027906dcfd0f4193f6b85472 100644 --- a/htdocs/fourn/card.php +++ b/htdocs/fourn/card.php @@ -366,8 +366,10 @@ if ($object->id > 0) $sql2.= ' AND s.rowid = '.$object->id; // Show orders with status validated, shipping started and delivered (well any order we can bill) $sql2.= " AND c.fk_statut IN (5)"; + $sql2.= " AND c.billed = 0"; // Find order that are not already invoiced - $sql2 .= " AND c.rowid NOT IN (SELECT fk_source FROM " . MAIN_DB_PREFIX . "element_element WHERE targettype='invoice_supplier')"; + // just need to check received status because we have the billed status now + //$sql2 .= " AND c.rowid NOT IN (SELECT fk_source FROM " . MAIN_DB_PREFIX . "element_element WHERE targettype='invoice_supplier')"; $resql2=$db->query($sql2); if ($resql2) { $orders2invoice = $db->num_rows($resql2); diff --git a/htdocs/fourn/class/fournisseur.commande.class.php b/htdocs/fourn/class/fournisseur.commande.class.php index 3f9d7b1246ae58893977e5c80ccfea7383b78802..5d509f8fd3a994df4fe5a7878730c6080fdbd27d 100644 --- a/htdocs/fourn/class/fournisseur.commande.class.php +++ b/htdocs/fourn/class/fournisseur.commande.class.php @@ -140,6 +140,7 @@ class CommandeFournisseur extends CommonOrder $this->statuts[5] = 'StatusOrderReceivedAll'; $this->statuts[6] = 'StatusOrderCanceled'; // Approved->Canceled $this->statuts[7] = 'StatusOrderCanceled'; // Process running->canceled + $this->statuts[8] = 'StatusOrderBilled'; // Everything is finish, order received totally and bill received $this->statuts[9] = 'StatusOrderRefused'; } @@ -164,7 +165,7 @@ class CommandeFournisseur extends CommonOrder $sql.= " c.fk_user_author, c.fk_user_valid, c.fk_user_approve, c.fk_user_approve2,"; $sql.= " c.date_commande as date_commande, c.date_livraison as date_livraison, c.fk_cond_reglement, c.fk_mode_reglement, c.fk_projet as fk_project, c.remise_percent, c.source, c.fk_input_method,"; $sql.= " c.fk_account,"; - $sql.= " c.note_private, c.note_public, c.model_pdf, c.extraparams,"; + $sql.= " c.note_private, c.note_public, c.model_pdf, c.extraparams, c.billed,"; $sql.= " cm.libelle as methode_commande,"; $sql.= " cr.code as cond_reglement_code, cr.libelle as cond_reglement_libelle,"; $sql.= " p.code as mode_reglement_code, p.libelle as mode_reglement_libelle"; @@ -197,6 +198,7 @@ class CommandeFournisseur extends CommonOrder $this->socid = $obj->fk_soc; $this->fourn_id = $obj->fk_soc; $this->statut = $obj->fk_statut; + $this->billed = $obj->billed; $this->user_author_id = $obj->fk_user_author; $this->user_valid_id = $obj->fk_user_valid; $this->user_approve_id = $obj->fk_user_approve; @@ -217,7 +219,6 @@ class CommandeFournisseur extends CommonOrder $this->methode_commande = $obj->methode_commande; $this->source = $obj->source; - //$this->facturee = $obj->facture; $this->fk_project = $obj->fk_project; $this->cond_reglement_id = $obj->fk_cond_reglement; $this->cond_reglement_code = $obj->cond_reglement_code; @@ -250,6 +251,7 @@ class CommandeFournisseur extends CommonOrder if ($this->statut == 0) $this->brouillon = 1; + $this->fetchObjectLinked(); $sql = "SELECT l.rowid, l.ref as ref_supplier, l.fk_product, l.product_type, l.label, l.description,"; $sql.= " l.qty,"; @@ -510,6 +512,8 @@ class CommandeFournisseur extends CommonOrder global $langs; $langs->load('orders'); + if($statut==5 && $this->billed == 1) $statut = 8; + // List of language codes for status $statutshort[0] = 'StatusOrderDraftShort'; $statutshort[1] = 'StatusOrderValidatedShort'; @@ -519,6 +523,7 @@ class CommandeFournisseur extends CommonOrder $statutshort[5] = 'StatusOrderReceivedAllShort'; $statutshort[6] = 'StatusOrderCanceledShort'; $statutshort[7] = 'StatusOrderCanceledShort'; + $statutshort[8] = 'StatusOrderBilledShort'; $statutshort[9] = 'StatusOrderRefusedShort'; if ($mode == 0) @@ -542,6 +547,7 @@ class CommandeFournisseur extends CommonOrder if ($statut==4) return img_picto($langs->trans($this->statuts[$statut]),'statut3'); if ($statut==5) return img_picto($langs->trans($this->statuts[$statut]),'statut6'); if ($statut==6 || $statut==7) return img_picto($langs->trans($this->statuts[$statut]),'statut5'); + if ($statut==8) return img_picto($langs->trans($this->statuts[$statut]),'statut6'); if ($statut==9) return img_picto($langs->trans($this->statuts[$statut]),'statut5'); } if ($mode == 4) @@ -553,6 +559,7 @@ class CommandeFournisseur extends CommonOrder if ($statut==4) return img_picto($langs->trans($this->statuts[$statut]),'statut3').' '.$langs->trans($this->statuts[$statut]); if ($statut==5) return img_picto($langs->trans($this->statuts[$statut]),'statut6').' '.$langs->trans($this->statuts[$statut]); if ($statut==6 || $statut==7) return img_picto($langs->trans($this->statuts[$statut]),'statut5').' '.$langs->trans($this->statuts[$statut]); + if ($statut==8) return img_picto($langs->trans($this->statuts[$statut]),'statut6').' '.$langs->trans($this->statuts[$statut]); if ($statut==9) return img_picto($langs->trans($this->statuts[$statut]),'statut5').' '.$langs->trans($this->statuts[$statut]); } if ($mode == 5) @@ -564,6 +571,7 @@ class CommandeFournisseur extends CommonOrder if ($statut==4) return '<span class="hideonsmartphone">'.$langs->trans($statutshort[$statut]).' </span>'.img_picto($langs->trans($this->statuts[$statut]),'statut3'); if ($statut==5) return '<span class="hideonsmartphone">'.$langs->trans($statutshort[$statut]).' </span>'.img_picto($langs->trans($this->statuts[$statut]),'statut6'); if ($statut==6 || $statut==7) return '<span class="hideonsmartphone">'.$langs->trans($statutshort[$statut]).' </span>'.img_picto($langs->trans($this->statuts[$statut]),'statut5'); + if ($statut==8) return '<span class="hideonsmartphone">'.$langs->trans($statutshort[$statut]).' </span>'.img_picto($langs->trans($this->statuts[$statut]),'statut6'); if ($statut==9) return '<span class="hideonsmartphone">'.$langs->trans($statutshort[$statut]).' </span>'.img_picto($langs->trans($this->statuts[$statut]),'statut5'); } } @@ -660,6 +668,26 @@ class CommandeFournisseur extends CommonOrder return -2; } } + /** + * Class invoiced the supplier order + * + * @return int <0 si ko, >0 si ok + */ + function classifyBilled() + { + $sql = 'UPDATE '.MAIN_DB_PREFIX.'commande_fournisseur SET billed = 1'; + $sql .= ' WHERE rowid = '.$this->id.' AND fk_statut > 0 '; + if ($this->db->query($sql) ) + { + $this->billed=1; + return 1; + } + else + { + dol_print_error($this->db); + return -1; + } + } /** * Approve a supplier order diff --git a/htdocs/fourn/commande/card.php b/htdocs/fourn/commande/card.php index 83b94bd74d9365594c6d27d69a470a055041e958..9a1a6ec67d4463eafef03dafec8e10f80066cd17 100644 --- a/htdocs/fourn/commande/card.php +++ b/htdocs/fourn/commande/card.php @@ -234,6 +234,17 @@ if (empty($reshook)) } } + /* + * Classify supplier order as billed + */ + if ($action == 'classifybilled' && $user->rights->fournisseur->commande->creer) + { + $ret=$object->classifyBilled(); + if ($ret < 0) { + setEventMessage($object->error, 'errors'); + } + } + /* * Add a line into product */ @@ -2725,18 +2736,19 @@ elseif (! empty($object->id)) // Create bill if (! empty($conf->facture->enabled)) { - if (! empty($conf->fournisseur->enabled) && ($object->statut >= 2 && $object->statut != 9)) // 2 means accepted + if (! empty($conf->fournisseur->enabled) && ($object->statut >= 2 && $object->billed != 1)) // 2 means accepted { if ($user->rights->fournisseur->facture->creer) { print '<a class="butAction" href="'.DOL_URL_ROOT.'/fourn/facture/card.php?action=create&origin='.$object->element.'&originid='.$object->id.'&socid='.$object->socid.'">'.$langs->trans("CreateBill").'</a>'; } - - //if ($user->rights->fournisseur->commande->creer && $object->statut > 2) - //{ - // print '<a class="butAction" href="'.$_SERVER["PHP_SELF"].'?id='.$object->id.'&action=classifybilled">'.$langs->trans("ClassifyBilled").'</a>'; - //} + + if ($user->rights->fournisseur->commande->creer && $object->statut >= 2 && !empty($object->linkedObjectsIds['invoice_supplier'])) + { + print '<a class="butAction" href="'.$_SERVER["PHP_SELF"].'?id='.$object->id.'&action=classifybilled">'.$langs->trans("ClassifyBilled").'</a>'; + } } + } // Create a remote order using WebService only if module is activated diff --git a/htdocs/fourn/commande/list.php b/htdocs/fourn/commande/list.php index ccffe5afa90c3efa83fd29e98406976ab336e3c6..dea0f72b6284222a552d9e4681835be9a94ce07a 100644 --- a/htdocs/fourn/commande/list.php +++ b/htdocs/fourn/commande/list.php @@ -167,6 +167,12 @@ if (GETPOST('statut', 'alpha') !== '') { $sql .= " AND cf.fk_statut IN (".GETPOST('statut', 'alpha').")"; } + +if (GETPOST('billed', 'int') !== '') +{ + $sql .= " AND cf.billed IN (".GETPOST('billed', 'int').")"; +} + if ($search_refsupp) { $sql.= " AND (cf.ref_supplier LIKE '%".$db->escape($search_refsupp)."%')"; diff --git a/htdocs/fourn/commande/orderstoinvoice.php b/htdocs/fourn/commande/orderstoinvoice.php index 2c12a9ccdcc244519d601e29aa2083615a39a6ca..d0502ed927a49b9176347b8011eb4e66870e93ca 100644 --- a/htdocs/fourn/commande/orderstoinvoice.php +++ b/htdocs/fourn/commande/orderstoinvoice.php @@ -236,9 +236,32 @@ if (($action == 'create' || $action == 'add') && empty($mesgs)) { // End of object creation, we show it if ($id > 0 && ! $error) { - $db->commit(); - header('Location: ' . DOL_URL_ROOT . '/fourn/facture/card.php?facid=' . $id); - exit(); + + foreach($orders_id as $fk_supplier_order) { + $supplier_order = new CommandeFournisseur($db); + if($supplier_order->fetch($fk_supplier_order)>0 && $supplier_order->statut == 5) { + + if($supplier_order->classifyBilled()<0) { + + $db->rollback(); + $action = 'create'; + $_GET["origin"] = $_POST["origin"]; + $_GET["originid"] = $_POST["originid"]; + $mesgs[] = '<div class="error">' . $object->error . '</div>'; + + $error++; + break; + } + + } + } + + if(!$error) { + $db->commit(); + header('Location: ' . DOL_URL_ROOT . '/fourn/facture/card.php?facid=' . $id); + exit(); + } + } else { $db->rollback(); $action = 'create'; @@ -406,9 +429,11 @@ if (($action != 'create' && $action != 'add') && !$error) { // Show orders with status validated, shipping started and delivered (well any order we can bill) $sql .= " AND c.fk_statut IN (5)"; + $sql .= " AND c.billed = 0"; // Find order that are not already invoiced - $sql .= " AND c.rowid NOT IN (SELECT fk_source FROM " . MAIN_DB_PREFIX . "element_element WHERE targettype='invoice_supplier')"; + //No need due to the billed status + //$sql .= " AND c.rowid NOT IN (SELECT fk_source FROM " . MAIN_DB_PREFIX . "element_element WHERE targettype='invoice_supplier')"; if ($socid) $sql .= ' AND s.rowid = ' . $socid; diff --git a/htdocs/install/mysql/migration/3.8.0-3.9.0.sql b/htdocs/install/mysql/migration/3.8.0-3.9.0.sql index d62a5f2505a97e0337bcafe5922804cdb00a9d6f..c472878a21c71ddc87913d950d5057e8704fa278 100755 --- a/htdocs/install/mysql/migration/3.8.0-3.9.0.sql +++ b/htdocs/install/mysql/migration/3.8.0-3.9.0.sql @@ -93,6 +93,9 @@ ALTER TABLE llx_societe_rib MODIFY COLUMN code_banque varchar(128); ALTER TABLE llx_contrat ADD COLUMN ref_customer varchar(30); ALTER TABLE llx_commande ADD COLUMN fk_warehouse integer DEFAULT NULL AFTER fk_shipping_method; +ALTER TABLE llx_commande_fournisseur ADD COLUMN billed smallint DEFAULT 0 AFTER fk_statut; +ALTER TABLE llx_commande_fournisseur ADD INDEX billed (billed); + ALTER TABLE llx_ecm_directories MODIFY COLUMN fullpath varchar(750); ALTER TABLE llx_ecm_directories DROP INDEX idx_ecm_directories; ALTER TABLE llx_ecm_directories ADD UNIQUE INDEX uk_ecm_directories (label, fk_parent, entity); diff --git a/htdocs/install/mysql/tables/llx_commande_fournisseur.key.sql b/htdocs/install/mysql/tables/llx_commande_fournisseur.key.sql index 1c10d6e3d702f0eea9f22f043d252449232c7799..d0d9471278aa4daf9bd10b2c0af27c96aade1458 100644 --- a/htdocs/install/mysql/tables/llx_commande_fournisseur.key.sql +++ b/htdocs/install/mysql/tables/llx_commande_fournisseur.key.sql @@ -25,3 +25,4 @@ ALTER TABLE llx_commande_fournisseur ADD UNIQUE INDEX uk_commande_fournisseur_re ALTER TABLE llx_commande_fournisseur ADD INDEX idx_commande_fournisseur_fk_soc (fk_soc); ALTER TABLE llx_commande_fournisseur ADD CONSTRAINT fk_commande_fournisseur_fk_soc FOREIGN KEY (fk_soc) REFERENCES llx_societe (rowid); +ALTER TABLE llx_commande_fournisseur ADD INDEX billed (billed); diff --git a/htdocs/install/mysql/tables/llx_commande_fournisseur.sql b/htdocs/install/mysql/tables/llx_commande_fournisseur.sql index 3b1dee31b9efea0960a34bb0ba0ae48793e60e18..18744a8ca2f29d61c29d84464a299591501ab5fa 100644 --- a/htdocs/install/mysql/tables/llx_commande_fournisseur.sql +++ b/htdocs/install/mysql/tables/llx_commande_fournisseur.sql @@ -45,6 +45,7 @@ create table llx_commande_fournisseur fk_user_approve2 integer, -- user approving 2 (when double approving is accivated) source smallint NOT NULL, -- not used, except by setting this to 42 for orders coming for replenishment and 0 in other case ? fk_statut smallint default 0, + billed smallint default 0, amount_ht real default 0, remise_percent real default 0, remise real default 0, diff --git a/htdocs/langs/en_US/orders.lang b/htdocs/langs/en_US/orders.lang index 3f635ad85b388043e46430c0a9f56f64328535bc..72985a9c0db8d2eaa7b62e5d916f1dbc87a4b674 100644 --- a/htdocs/langs/en_US/orders.lang +++ b/htdocs/langs/en_US/orders.lang @@ -35,6 +35,7 @@ StatusOrderToBillShort=Delivered StatusOrderToBill2Short=To bill StatusOrderApprovedShort=Approved StatusOrderRefusedShort=Refused +StatusOrderBilledShort=Billed StatusOrderToProcessShort=To process StatusOrderReceivedPartiallyShort=Partially received StatusOrderReceivedAllShort=Everything received @@ -48,6 +49,7 @@ StatusOrderToBill=Delivered StatusOrderToBill2=To bill StatusOrderApproved=Approved StatusOrderRefused=Refused +StatusOrderBilled=Billed StatusOrderReceivedPartially=Partially received StatusOrderReceivedAll=Everything received ShippingExist=A shipment exists