From d09935728268b032a5c7af4fd44813bf2c1c3dbb Mon Sep 17 00:00:00 2001 From: abumuhammad Date: Wed, 12 Sep 2018 10:07:41 +0700 Subject: [PATCH] Fitur Pesanan Penjualan / Sales Order : Draft --- kodesurat/kodenomorjenissurat | 1 + .../PesananpenjualanController.php | 163 ++++++++++++++++++ ..._034955_create_table_pesanan_penjualan.php | 13 +- protected/models/KodeDokumen.php | 3 +- protected/models/PesananPenjualan.php | 60 +++++-- protected/views/pesananpenjualan/_form.php | 53 ++++++ protected/views/pesananpenjualan/index.php | 74 ++++++++ protected/views/pesananpenjualan/tambah.php | 54 ++++++ protected/views/pesananpenjualan/ubah.php | 46 +++++ protected/views/pesananpenjualan/view.php | 68 ++++++++ 10 files changed, 519 insertions(+), 16 deletions(-) create mode 100644 protected/controllers/PesananpenjualanController.php create mode 100644 protected/views/pesananpenjualan/_form.php create mode 100644 protected/views/pesananpenjualan/index.php create mode 100644 protected/views/pesananpenjualan/tambah.php create mode 100644 protected/views/pesananpenjualan/ubah.php create mode 100644 protected/views/pesananpenjualan/view.php diff --git a/kodesurat/kodenomorjenissurat b/kodesurat/kodenomorjenissurat index 2b11ee64..374f777e 100644 --- a/kodesurat/kodenomorjenissurat +++ b/kodesurat/kodenomorjenissurat @@ -11,3 +11,4 @@ contoh: 0101141200001 [kode_kantor][kode_surat][tahun][bulan][nomor_urut] 09 Penerimaan IN 10 Anjungan Kasir Mandiri AK 11 Purchase Order PO +12 Sales Order LO diff --git a/protected/controllers/PesananpenjualanController.php b/protected/controllers/PesananpenjualanController.php new file mode 100644 index 00000000..76b4be51 --- /dev/null +++ b/protected/controllers/PesananpenjualanController.php @@ -0,0 +1,163 @@ +render('view', [ + 'model' => $this->loadModel($id), + ]); + } + + /** + * Creates a new model. + * If creation is successful, the browser will be redirected to the 'view' page. + */ + public function actionTambah() + { + $this->layout = '//layouts/box_kecil'; + $model = new PesananPenjualan; + + // Uncomment the following line if AJAX validation is needed + // $this->performAjaxValidation($model); + + if (isset($_POST['PesananPenjualan'])) { + $model->attributes = $_POST['PesananPenjualan']; + if ($model->save()) + $this->redirect(['view', 'id' => $model->id]); + } + + $customerList = Profil::model()->findAll([ + 'select' => 'id, nama', + 'condition' => 'id>' . Profil::AWAL_ID . ' and tipe_id=' . Profil::TIPE_CUSTOMER, + 'order' => 'nama']); + + $this->render('tambah', [ + 'model' => $model, + 'customerList' => $customerList, + ]); + } + + /** + * Updates a particular model. + * @param integer $id the ID of the model to be updated + */ + public function actionUbah($id) + { + $model = $this->loadModel($id); + + // Uncomment the following line if AJAX validation is needed + // $this->performAjaxValidation($model); + + if (isset($_POST['PesananPenjualan'])) { + $model->attributes = $_POST['PesananPenjualan']; + if ($model->save()) + $this->redirect(['view', 'id' => $id]); + } + + $this->render('ubah', [ + 'model' => $model, + ]); + } + + /** + * Deletes a particular model. + * If deletion is successful, the browser will be redirected to the 'admin' page. + * @param integer $id the ID of the model to be deleted + */ + public function actionHapus($id) + { + $this->loadModel($id)->delete(); + + // if AJAX request (triggered by deletion via admin grid view), we should not redirect the browser + if (!isset($_GET['ajax'])) + $this->redirect(isset($_POST['returnUrl']) ? $_POST['returnUrl'] : ['index']); + } + + /** + * Manages all models. + */ + public function actionIndex() + { + $model = new PesananPenjualan('search'); + $model->unsetAttributes(); // clear any default values + if (isset($_GET['PesananPenjualan'])) + $model->attributes = $_GET['PesananPenjualan']; + + $this->render('index', [ + 'model' => $model, + ]); + } + + /** + * Returns the data model based on the primary key given in the GET variable. + * If the data model is not found, an HTTP exception will be raised. + * @param integer $id the ID of the model to be loaded + * @return PesananPenjualan the loaded model + * @throws CHttpException + */ + public function loadModel($id) + { + $model = PesananPenjualan::model()->findByPk($id); + if ($model === null) + throw new CHttpException(404, 'The requested page does not exist.'); + return $model; + } + + /** + * Performs the AJAX validation. + * @param PesananPenjualan $model the model to be validated + */ + protected function performAjaxValidation($model) + { + if (isset($_POST['ajax']) && $_POST['ajax'] === 'pesanan-penjualan-form') { + echo CActiveForm::validate($model); + Yii::app()->end(); + } + } + + /** + * render nomor + * @param obj $data + * @return string nomor, beserta link yang sesuai + */ + public function renderLinkNomor($data) + { + switch ($data->status) { + case PesananPenjualan::STATUS_BATAL: + return $data->nomor; + break; + + case PesananPenjualan::STATUS_JUAL: + return '' . $data->nomor . ''; + break; + + case PesananPenjualan::STATUS_PESAN: + return '' . $data->nomor . ''; + break; + } + } + + /** + * render link actionUbah jika belum ada nomor + * @param obj $data + * @return string tanggal, beserta link jika masih draft (belum ada nomor) + */ + public function renderLinkTanggalToUbah($data) + { + if (!isset($data->nomor)) { + $return = '' . + $data->tanggal . ''; + } else { + $return = $data->tanggal; + } + return $return; + } + +} diff --git a/protected/migrations/m180910_034955_create_table_pesanan_penjualan.php b/protected/migrations/m180910_034955_create_table_pesanan_penjualan.php index 3dd3d5cb..e5090753 100644 --- a/protected/migrations/m180910_034955_create_table_pesanan_penjualan.php +++ b/protected/migrations/m180910_034955_create_table_pesanan_penjualan.php @@ -13,14 +13,17 @@ public function safeUp() `nomor` varchar(45) DEFAULT NULL, `tanggal` datetime NOT NULL, `profil_id` int(10) unsigned NOT NULL, - `status` tinyint(3) unsigned NOT NULL DEFAULT '0' COMMENT '0:draft; 1:simpan;', + `penjualan_id` INT UNSIGNED NULL, + `status` tinyint(3) unsigned NOT NULL DEFAULT '0' COMMENT '0:draft; 10:pesan; 20:batal; 30:jual;', `updated_at` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, - `updated_by` int(10) unsigned NOT NULL, + `updated_by` int(10) unsigned NOT NULL, `created_at` timestamp NOT NULL DEFAULT '2000-01-01 00:00:00', PRIMARY KEY (`id`), UNIQUE KEY `nomor_UNIQUE` (`nomor`), - KEY `fk_pesanan_penjualan_updatedby_idx` (`updated_by`), - CONSTRAINT `fk_pesanan_penjualan_updatedby` FOREIGN KEY (`updated_by`) REFERENCES `user` (`id`) ON DELETE NO ACTION ON UPDATE NO ACTION + KEY `fk_pesanan_penjualan_updatedby_idx` (`updated_by`), + KEY `fk_pesanan_penjualan_penjualan_idx` (`penjualan_id`), + CONSTRAINT `fk_pesanan_penjualan_updatedby` FOREIGN KEY (`updated_by`) REFERENCES `user` (`id`) ON DELETE NO ACTION ON UPDATE NO ACTION, + CONSTRAINT `fk_pesanan_penjualan_penjualan` FOREIGN KEY (`penjualan_id`) REFERENCES `penjualan` (`id`) ON DELETE NO ACTION ON UPDATE NO ACTION ", ], $tableOption); @@ -33,7 +36,7 @@ public function safeUp() `harga_jual` decimal(18,2) NOT NULL, `diskon` decimal(18,2) DEFAULT NULL, `updated_at` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, - `updated_by` int(10) unsigned NOT NULL, + `updated_by` int(10) unsigned NOT NULL, `created_at` timestamp NULL DEFAULT NULL, PRIMARY KEY (`id`), KEY `fk_pesanan_penjualan_detail_header_idx` (`pesanan_penjualan_id`), diff --git a/protected/models/KodeDokumen.php b/protected/models/KodeDokumen.php index 48152977..a10d68f5 100644 --- a/protected/models/KodeDokumen.php +++ b/protected/models/KodeDokumen.php @@ -28,7 +28,8 @@ class KodeDokumen extends CActiveRecord const PENGELUARAN = '08'; const PENERIMAAN = '09'; const AKM = '10'; - const PO = '11'; + const PO = '11'; // PURCHASE ORDER + const PESANAN_PENJUALAN = '12'; // SALES ORDER /** * @return string the associated database table name diff --git a/protected/models/PesananPenjualan.php b/protected/models/PesananPenjualan.php index 2687dae6..0f1b20b1 100644 --- a/protected/models/PesananPenjualan.php +++ b/protected/models/PesananPenjualan.php @@ -8,18 +8,25 @@ * @property string $nomor * @property string $tanggal * @property string $profil_id + * @property string $penjualan_id * @property integer $status * @property string $updated_at * @property string $updated_by * @property string $created_at * * The followings are the available model relations: + * @property Penjualan $penjualan * @property User $updatedBy * @property PesananPenjualanDetail[] $pesananPenjualanDetails */ class PesananPenjualan extends CActiveRecord { + const STATUS_DRAFT = 0; + const STATUS_PESAN = 10; + const STATUS_BATAL = 20; + const STATUS_JUAL = 30; + /** * @return string the associated database table name */ @@ -39,11 +46,11 @@ public function rules() ['tanggal, profil_id', 'required'], ['status', 'numerical', 'integerOnly' => true], ['nomor', 'length', 'max' => 45], - ['profil_id, updated_by', 'length', 'max' => 10], + ['profil_id, penjualan_id, updated_by', 'length', 'max' => 10], ['created_at, updated_at, updated_by', 'safe'], // The following rule is used by search(). // @todo Please remove those attributes that should not be searched. - ['id, nomor, tanggal, profil_id, status, updated_at, updated_by, created_at', 'safe', 'on' => 'search'], + ['id, nomor, tanggal, profil_id, penjualan_id, status, updated_at, updated_by, created_at', 'safe', 'on' => 'search'], ]; } @@ -55,6 +62,7 @@ public function relations() // NOTE: you may need to adjust the relation name and the related // class name for the relations automatically generated below. return [ + 'penjualan' => [self::BELONGS_TO, 'Penjualan', 'penjualan_id'], 'updatedBy' => [self::BELONGS_TO, 'User', 'updated_by'], 'pesananPenjualanDetails' => [self::HAS_MANY, 'PesananPenjualanDetail', 'pesanan_penjualan_id'], ]; @@ -66,14 +74,15 @@ public function relations() public function attributeLabels() { return [ - 'id' => 'ID', - 'nomor' => 'Nomor', - 'tanggal' => 'Tanggal', - 'profil_id' => 'Profil', - 'status' => 'Status', - 'updated_at' => 'Updated At', - 'updated_by' => 'Updated By', - 'created_at' => 'Created At', + 'id' => 'ID', + 'nomor' => 'Nomor', + 'tanggal' => 'Tanggal', + 'profil_id' => 'Profil', + 'penjualan_id' => 'Penjualan', + 'status' => 'Status', + 'updated_at' => 'Updated At', + 'updated_by' => 'Updated By', + 'created_at' => 'Created At', ]; } @@ -99,6 +108,7 @@ public function search() $criteria->compare('nomor', $this->nomor, true); $criteria->compare('tanggal', $this->tanggal, true); $criteria->compare('profil_id', $this->profil_id); + $criteria->compare('penjualan_id', $this->penjualan_id); $criteria->compare('status', $this->status); $criteria->compare('updated_at', $this->updated_at, true); $criteria->compare('updated_by', $this->updated_by, true); @@ -131,4 +141,34 @@ public function beforeSave() return parent::beforeSave(); } + /** + * Mencari nomor untuk penomoran surat + * @return int maksimum+1 atau 1 jika belum ada nomor untuk tahun ini + */ + public function cariNomor() + { + $tahun = date('y'); + $data = $this->find([ + 'select' => 'max(substring(nomor,9)*1) as max', + 'condition' => "substring(nomor,5,2)='{$tahun}'"] + ); + + $value = is_null($data) ? 0 : $data->max; + return $value + 1; + } + + /** + * Membuat nomor surat + * @return string Nomor sesuai format "[KodeCabang][kodeDokumen][Tahun][Bulan][SequenceNumber]" + */ + public function generateNomor() + { + $config = Config::model()->find("nama='toko.kode'"); + $kodeCabang = $config->nilai; + $kodeDokumen = KodeDokumen::PESANAN_PENJUALAN; + $kodeTahunBulan = date('ym'); + $sequence = substr('00000' . $this->cariNomor(), -6); + return "{$kodeCabang}{$kodeDokumen}{$kodeTahunBulan}{$sequence}"; + } + } diff --git a/protected/views/pesananpenjualan/_form.php b/protected/views/pesananpenjualan/_form.php new file mode 100644 index 00000000..5a5c7d0f --- /dev/null +++ b/protected/views/pesananpenjualan/_form.php @@ -0,0 +1,53 @@ + + +
+ + beginWidget('CActiveForm', + [ + 'id' => 'pesanan-penjualan-form', + // Please note: When you enable ajax validation, make sure the corresponding + // controller action is handling ajax validation correctly. + // There is a call to performAjaxValidation() commented in generated controller code. + // See class documentation of CActiveForm for details on this. + 'enableAjaxValidation' => false, + ]); + ?> + + errorSummary($model, 'Error: Perbaiki input', null, ['class' => 'panel callout']); ?> + + +
+
+ labelEx($model, 'profil_id'); ?> + dropDownList($model, 'profil_id', CHtml::listData($customerList, 'id', 'nama'), + [ + 'empty' => 'UMUM', + 'autofocus' => 'autofocus' + ]); + ?> + error($model, 'profil_id', ['class' => 'error']); ?> +
+
+
+
+ +
+
+ +
+
+ isNewRecord ? 'Tambah' : 'Simpan', ['class' => 'tiny bigfont button']); + ?> +
+
+ + endWidget(); ?> + +
\ No newline at end of file diff --git a/protected/views/pesananpenjualan/index.php b/protected/views/pesananpenjualan/index.php new file mode 100644 index 00000000..a8ee8a86 --- /dev/null +++ b/protected/views/pesananpenjualan/index.php @@ -0,0 +1,74 @@ +breadcrumbs = [ + 'Pesanan Penjualan' => ['index'], + 'Index', +]; + +$this->boxHeader['small'] = 'Pesanan Penjualan'; +$this->boxHeader['normal'] = 'Pesanan Penjualan'; + +$this->widget('BGridView', + [ + 'id' => 'pesanan-penjualan-grid', + 'dataProvider' => $model->search(), + 'filter' => $model, + 'columns' => [ + [ + 'class' => 'BDataColumn', + 'name' => 'nomor', + 'header' => 'Nomor', + 'accesskey' => 'n', + 'type' => 'raw', + 'value' => [$this, 'renderLinkNomor'] + ], + [ + 'class' => 'BDataColumn', + 'name' => 'tanggal', + 'header' => 'Tanggal', + 'accesskey' => 'l', + 'type' => 'raw', + 'value' => [$this, 'renderLinkTanggalToUbah'] + ], + 'profil_id', + 'status', + 'updated_by', + [ + 'class' => 'BButtonColumn', + ], + ], +]); + +$this->menu = [ + ['itemOptions' => ['class' => 'divider'], 'label' => ''], + [ + 'itemOption' => ['class' => 'has-form hide-for-small-only'], + 'label' => '', + 'items' => [ + [ + 'label' => ' Tambah', + 'url' => $this->createUrl('tambah'), + 'linkOptions' => [ + 'class' => 'button', + 'accesskey' => 't' + ]], + ], + 'submenuOptions' => ['class' => 'button-group'] + ], + [ + 'itemOptions' => ['class' => 'has-form show-for-small-only'], + 'label' => '', + 'items' => [ + [ + 'label' => '', + 'url' => $this->createUrl('tambah'), + 'linkOptions' => [ + 'class' => 'button', + ]], + ], + 'submenuOptions' => ['class' => 'button-group'] + ] +]; diff --git a/protected/views/pesananpenjualan/tambah.php b/protected/views/pesananpenjualan/tambah.php new file mode 100644 index 00000000..4080ab32 --- /dev/null +++ b/protected/views/pesananpenjualan/tambah.php @@ -0,0 +1,54 @@ +breadcrumbs = [ + 'Pesanan Penjualan' => ['index'], + 'Tambah', +]; + +$this->boxHeader['small'] = 'Tambah'; +$this->boxHeader['normal'] = 'Tambah Pesanan Penjualan'; +?> +renderPartial('_form', [ + 'model' => $model, + 'customerList' => $customerList,]); +?> + +menu = [ + [ + 'itemOptions' => ['class' => 'divider'], 'label' => false + ], + [ + 'itemOptions' => ['class' => 'has-form hide-for-small-only'], + 'label' => false, + 'items' => [ + [ + 'label' => ' Index', + 'url' => $this->createUrl('index'), + 'linkOptions' => [ + 'class' => 'success button', + 'accesskey' => 'i' + ]] + ], + 'submenuOptions' => ['class' => 'button-group'] + ], + [ + 'itemOptions' => ['class' => 'has-form show-for-small-only'], + 'label' => false, + 'items' => [ + [ + 'label' => '', + 'url' => $this->createUrl('index'), + 'linkOptions' => [ + 'class' => 'success button', + ]], + ], + 'submenuOptions' => ['class' => 'button-group'] + ] +]; diff --git a/protected/views/pesananpenjualan/ubah.php b/protected/views/pesananpenjualan/ubah.php new file mode 100644 index 00000000..9a0bc1eb --- /dev/null +++ b/protected/views/pesananpenjualan/ubah.php @@ -0,0 +1,46 @@ +breadcrumbs=array( + 'Pesanan Penjualan'=>array('index'), + $model->id=>array('view','id'=>$model->id), + 'Ubah', +); + +$this->boxHeader['small'] = 'Ubah'; +$this->boxHeader['normal'] = "Pesanan Penjualan: {$model->nama}"; +?> +
+
+ renderPartial('_form', array('model'=>$model)); ?> +
+
+menu = array( + array('itemOptions' => array('class' => 'divider'), 'label' => false), + array('itemOptions' => array('class' => 'has-form hide-for-small-only'), 'label' => false, + 'items' => array( + array('label' => ' Tambah', 'url' => $this->createUrl('tambah'), 'linkOptions' => array( + 'class' => 'button', + 'accesskey' => 't' + )), + array('label' => ' Index', 'url' => $this->createUrl('index'), 'linkOptions' => array( + 'class' => 'success button', + 'accesskey' => 'i' + )) + ), + 'submenuOptions' => array('class' => 'button-group') + ), + array('itemOptions' => array('class' => 'has-form show-for-small-only'), 'label' => false, + 'items' => array( + array('label' => '', 'url' => $this->createUrl('tambah'), 'linkOptions' => array( + 'class' => 'button', + )), + array('label' => '', 'url' => $this->createUrl('index'), 'linkOptions' => array( + 'class' => 'success button', + )) + ), + 'submenuOptions' => array('class' => 'button-group') + ) +); \ No newline at end of file diff --git a/protected/views/pesananpenjualan/view.php b/protected/views/pesananpenjualan/view.php new file mode 100644 index 00000000..726dd3ec --- /dev/null +++ b/protected/views/pesananpenjualan/view.php @@ -0,0 +1,68 @@ +breadcrumbs=array( + 'Pesanan Penjualan'=>array('index'), + $model->id, +); + +$this->boxHeader['small'] = 'View'; +$this->boxHeader['normal'] = 'Pesanan Penjualan: '.$model->nama; +?> +
+
+widget('BDetailView', array( + 'data'=>$model, + 'attributes'=>array( + 'id', + 'nomor', + 'tanggal', + 'profil_id', + 'status', + 'updated_at', + 'updated_by', + 'created_at', + ), +)); ?> +
+
+menu = array( + array('itemOptions' => array('class' => 'divider'), 'label' => false), + array('itemOptions' => array('class' => 'has-form hide-for-small-only'), 'label' => false, + 'items' => array( + array('label' => ' Ubah', 'url' => $this->createUrl('ubah', array('id' => $model->id)), 'linkOptions' => array( + 'class' => 'button', + 'accesskey' => 'u' + )), + array('label' => ' Hapus', 'url' => $this->createUrl('hapus', array('id' => $model->id)), 'linkOptions' => array( + 'class' => 'alert button', + 'accesskey' => 'h', + 'submit'=>array('hapus','id'=>$model->id), + 'confirm'=>'Anda yakin?' + )), + array('label' => ' Index', 'url' => $this->createUrl('index'), 'linkOptions' => array( + 'class' => 'success button', + 'accesskey' => 'i' + )) + ), + 'submenuOptions' => array('class' => 'button-group') + ), + array('itemOptions' => array('class' => 'has-form show-for-small-only'), 'label' => false, + 'items' => array( + array('label' => '', 'url' => $this->createUrl('ubah', array('id' => $model->id)), 'linkOptions' => array( + 'class' => 'button', + )), + array('label' => '', 'url' => $this->createUrl('hapus', array('id' => $model->id)), 'linkOptions' => array( + 'class' => 'alert button', + 'submit'=>array('hapus','id'=>$model->id), + 'confirm'=>'Anda yakin?' + )), + array('label' => '', 'url' => $this->createUrl('index'), 'linkOptions' => array( + 'class' => 'success button', + )) + ), + 'submenuOptions' => array('class' => 'button-group') + ) +); \ No newline at end of file